Merge pull request #2869 from BrzVlad/feature-mod-union-opt
[mono.git] / mcs / mcs / codegen.cs
index c224b0d636a7056fa2632b123768c36e69db10b3..d5ba75c12813af9d07e4b3182134f82cc3e557f9 100644 (file)
@@ -317,20 +317,20 @@ namespace Mono.CSharp
                        ig.BeginFinallyBlock ();
                }
 
-               public void BeginScope ()
+               public void BeginScope (int scopeIndex)
                {
                        if ((flags & Options.OmitDebugInfo) != 0)
                                return;
 
-                       methodSymbols.StartBlock (CodeBlockEntry.Type.Lexical, ig.ILOffset);
+                       methodSymbols.StartBlock (CodeBlockEntry.Type.Lexical, ig.ILOffset, scopeIndex);
                }
 
-               public void BeginCompilerScope ()
+               public void BeginCompilerScope (int scopeIndex)
                {
                        if ((flags & Options.OmitDebugInfo) != 0)
                                return;
 
-                       methodSymbols.StartBlock (CodeBlockEntry.Type.CompilerGenerated, ig.ILOffset);
+                       methodSymbols.StartBlock (CodeBlockEntry.Type.CompilerGenerated, ig.ILOffset, scopeIndex);
                }
 
                public void EndExceptionBlock ()
@@ -390,6 +390,22 @@ namespace Mono.CSharp
                        if (IsAnonymousStoreyMutateRequired)
                                type = CurrentAnonymousMethod.Storey.Mutator.Mutate (type);
 
+                       if (pinned) {
+                               //
+                               // This is for .net compatibility. I am not sure why pinned
+                               // pointer temps are converted to & even if they are pointers to
+                               // pointers.
+                               //
+                               var pt = type as PointerContainer;
+                               if (pt != null) {
+                                       type = pt.Element;
+                                       if (type.Kind == MemberKind.Void)
+                                               type = Module.Compiler.BuiltinTypes.IntPtr;
+                                       
+                                       return ig.DeclareLocal (type.GetMetaInfo ().MakeByRefType (), true);
+                               }
+                       }
+
                        return ig.DeclareLocal (type.GetMetaInfo (), pinned);
                }
 
@@ -1247,10 +1263,15 @@ namespace Mono.CSharp
 
                        if (conditionalAccess) {
                                if (!ec.ConditionalAccess.Statement) {
-                                       if (ec.ConditionalAccess.Type.IsNullableType)
-                                               Nullable.LiftedNull.Create (ec.ConditionalAccess.Type, Location.Null).Emit (ec);
-                                       else
+                                       var t = ec.ConditionalAccess.Type;
+                                       if (t.IsNullableType)
+                                               Nullable.LiftedNull.Create (t, Location.Null).Emit (ec);
+                                       else {
                                                ec.EmitNull ();
+
+                                               if (t.IsGenericParameter)
+                                                       ec.Emit (OpCodes.Unbox_Any, t);
+                                       }
                                }
 
                                ec.Emit (OpCodes.Br, ec.ConditionalAccess.EndLabel);