[linker] do not set scope of non-marked typerefs
authorRadek Doulik <rodo@xamarin.com>
Tue, 16 Feb 2016 21:21:58 +0000 (22:21 +0100)
committerRadek Doulik <rodo@xamarin.com>
Tue, 16 Feb 2016 21:44:29 +0000 (22:44 +0100)
 - fixes #38818

 - setting the *unchanged* scope to non-marked types is harmful,
   because in case the type has declaring type, the scope of declaring
   type is set as well. see
   https://github.com/mono/cecil/blob/master/Mono.Cecil/TypeReference.cs#L132

   public virtual IMetadataScope Scope {
      get ...
      set {
          var declaring_type = this.DeclaringType;
          if (declaring_type != null) {
              declaring_type.Scope = value;
              return;
          }
          scope = value;
      }
   }

   so in our case, we first set correctly scope of
   System.Collections.Generic.Dictionary`2 to mscorlib, then (re)set
   scope of System.Collections.Generic.Dictionary`2/ValueCollection
   and
   System.Collections.Generic.Dictionary`2/ValueCollection/Enumerator
   to System.Collection (note that these types are not marked and are
   swept away by linker), which sets scope of its declaring type
   System.Collections.Generic.Dictionary`2 back to System.Collection

   and because the System.Collection is linked-out, the typeref is
   incorrectly written with the scope set to System later

mcs/tools/linker/Mono.Linker.Steps/SweepStep.cs

index 386028acad43daafa4dd5d81fc945d5c0114bea5..e463ff9cde8d982212c5ead62160b37ef461cb7b 100644 (file)
@@ -155,8 +155,8 @@ namespace Mono.Linker.Steps {
                                        scope = assembly.MainModule.Import (td).Scope;
                                        if (tr.Scope != scope)
                                                changes = true;
+                                       hash.Add (tr, scope);
                                }
-                               hash.Add (tr, scope);
                        }
                        if (assembly.MainModule.HasExportedTypes) {
                                foreach (var et in assembly.MainModule.ExportedTypes) {