[mcs] Report second level references mismatch only for really used references. Fixes...
authorMarek Safar <masafa@microsoft.com>
Wed, 10 Aug 2016 13:54:04 +0000 (15:54 +0200)
committerMarek Safar <masafa@microsoft.com>
Wed, 10 Aug 2016 13:54:04 +0000 (15:54 +0200)
mcs/mcs/assembly.cs
mcs/mcs/ikvm.cs
mcs/tests/Makefile
mcs/tests/dlls/test-939-1/test-939-lib.cs [new file with mode: 0644]
mcs/tests/dlls/test-939-1/test-939-ref.cs [new file with mode: 0644]
mcs/tests/dlls/test-939-2/test-939-lib.cs [new file with mode: 0644]
mcs/tests/dlls/test-939-common.cs [new file with mode: 0644]
mcs/tests/test-939.cs [new file with mode: 0644]
mcs/tests/ver-il-net_4_x.xml

index 004d29f8bd25dec87cc69901bd57b869d37cf9b5..85dff2b3c84fcb71651275ea08fb316c379f9d64 100644 (file)
@@ -20,6 +20,7 @@ using System.Security.Cryptography;
 using System.Security.Permissions;
 using Mono.Security.Cryptography;
 using Mono.CompilerServices.SymbolWriter;
+using System.Linq;
 
 #if STATIC
 using IKVM.Reflection;
@@ -43,6 +44,20 @@ namespace Mono.CSharp
                byte[] GetPublicKeyToken ();
                bool IsFriendAssemblyTo (IAssemblyDefinition assembly);
        }
+
+       public class AssemblyReferenceErrorInfo
+       {
+               public AssemblyReferenceErrorInfo (AssemblyName dependencyName, string location, string message)
+               {
+                       this.DependencyName = dependencyName;
+                       this.RequestingAssemblyLocation = location;
+                       this.Message = message;
+               }
+
+               public AssemblyName DependencyName { get; private set; }
+               public string RequestingAssemblyLocation { get; private set; }
+               public string Message { get; private set; }
+       }
                 
        public abstract class AssemblyDefinition : IAssemblyDefinition
        {
@@ -416,7 +431,8 @@ namespace Mono.CSharp
                //
                void CheckReferencesPublicToken ()
                {
-                       foreach (var an in builder_extra.GetReferencedAssemblies ()) {
+                       var references = builder_extra.GetReferencedAssemblies ();
+                       foreach (var an in references) {
                                if (public_key != null && an.GetPublicKey ().Length == 0) {
                                        Report.Error (1577, "Referenced assembly `{0}' does not have a strong name",
                                                an.FullName);
@@ -432,11 +448,17 @@ namespace Mono.CSharp
                                if (ia == null)
                                        continue;
 
-                               var references = GetNotUnifiedReferences (an);
-                               if (references != null) {
-                                       foreach (var r in references) {
-                                               Report.SymbolRelatedToPreviousError ( r[0]);
-                                               Report.Error (1705, r [1]);
+                               var an_references = GetNotUnifiedReferences (an);
+                               if (an_references != null) {
+                                       foreach (var r in an_references) {
+                                               //
+                                               // Secondary check when assembly references is resolved but not used. For example
+                                               // due to type-forwarding
+                                               //
+                                               if (references.Any (l => l.Name == r.DependencyName.Name)) {
+                                                       Report.SymbolRelatedToPreviousError (r.RequestingAssemblyLocation);
+                                                       Report.Error (1705, r.Message);
+                                               }
                                        }
                                }
 
@@ -570,7 +592,7 @@ namespace Mono.CSharp
                        return public_key_token;
                }
 
-               protected virtual List<string[]> GetNotUnifiedReferences (AssemblyName assemblyName)
+               protected virtual List<AssemblyReferenceErrorInfo> GetNotUnifiedReferences (AssemblyName assemblyName)
                {
                        return null;
                }
index 75a02034f9cf9cda8bef266f139325a055c15546..f4b9930f3999e8c3395d53a4319744d1130492c0 100644 (file)
@@ -220,7 +220,7 @@ namespace Mono.CSharp
                        return Builder.__AddModule (moduleFile);
                }
 
-               protected override List<string[]> GetNotUnifiedReferences (AssemblyName assemblyName)
+               protected override List<AssemblyReferenceErrorInfo> GetNotUnifiedReferences (AssemblyName assemblyName)
                {
                        return loader.GetNotUnifiedReferences (assemblyName);
                }
@@ -238,7 +238,7 @@ namespace Mono.CSharp
                Assembly corlib;
                readonly List<Tuple<AssemblyName, string, Assembly>> loaded_names;
                static readonly Dictionary<string, string[]> sdk_directory;
-               Dictionary<AssemblyName, List<string[]>> resolved_version_mismatches;
+               Dictionary<AssemblyName, List<AssemblyReferenceErrorInfo>> resolved_version_mismatches;
                static readonly TypeName objectTypeName = new TypeName ("System", "Object");
 
                static StaticLoader ()
@@ -359,25 +359,24 @@ namespace Mono.CSharp
                                if (version_mismatch is AssemblyBuilder)
                                        return version_mismatch;
 
-                               var v1 = new AssemblyName (refname).Version;
+                               var ref_an = new AssemblyName (refname);
+                               var v1 = ref_an.Version;
                                var v2 = version_mismatch.GetName ().Version;
 
                                if (v1 > v2) {
                                        if (resolved_version_mismatches == null)
-                                               resolved_version_mismatches = new Dictionary<AssemblyName, List<string[]>> ();
+                                               resolved_version_mismatches = new Dictionary<AssemblyName, List<AssemblyReferenceErrorInfo>> ();
 
                                        var an = args.RequestingAssembly.GetName ();
-                                       List<string[]> names;
+                                       List<AssemblyReferenceErrorInfo> names;
                                        if (!resolved_version_mismatches.TryGetValue (an, out names)) {
-                                               names = new List<string[]> ();
+                                               names = new List<AssemblyReferenceErrorInfo> ();
                                                resolved_version_mismatches.Add (an, names);
                                        }
 
-                                       names.Add (new[] {
-                                               args.RequestingAssembly.Location,
+                                       names.Add (new AssemblyReferenceErrorInfo (ref_an, args.RequestingAssembly.Location,
                                                string.Format ("Assembly `{0}' depends on `{1}' which has a higher version number than referenced assembly `{2}'",
-                                                       args.RequestingAssembly.FullName, refname, version_mismatch.GetName ().FullName)
-                                       });
+                                                          args.RequestingAssembly.FullName, refname, version_mismatch.GetName ().FullName)));
 
                                        return version_mismatch;
                                }
@@ -434,9 +433,9 @@ namespace Mono.CSharp
                        return default_references.ToArray ();
                }
 
-               public List<string[]> GetNotUnifiedReferences (AssemblyName assemblyName)
+               public List<AssemblyReferenceErrorInfo> GetNotUnifiedReferences (AssemblyName assemblyName)
                {
-                       List<string[]> list = null;
+                       List<AssemblyReferenceErrorInfo> list = null;
                        if (resolved_version_mismatches != null)
                                resolved_version_mismatches.TryGetValue (assemblyName, out list);
 
index 10674f5cd9ec50902bc0db9d25355599b17fa65d..a149e2eb536cb3f61714de3073ead029a3aa9405 100644 (file)
@@ -98,4 +98,8 @@ csproj-local:
 setup:
        $(CSCOMPILE) -t:library dlls/test-679-2/test-679-lib-2.cs
        $(CSCOMPILE) -t:library dlls/test-679-1/test-679-lib.cs -r:dlls/test-679-2/test-679-lib-2.dll
+       $(CSCOMPILE) -t:library dlls/test-939-common.cs -keyfile:key.snk -publicsign
+       $(CSCOMPILE) -t:library dlls/test-939-1/test-939-lib.cs -keyfile:key.snk -publicsign
+       $(CSCOMPILE) -t:library dlls/test-939-1/test-939-ref.cs -r:dlls/test-939-1/test-939-lib.dll -keyfile:key.snk -publicsign
+       $(CSCOMPILE) -t:library dlls/test-939-2/test-939-lib.cs -r:dlls/test-939-common.dll -keyfile:key.snk -publicsign
        $(ILASM) -dll dlls/test-883.il
diff --git a/mcs/tests/dlls/test-939-1/test-939-lib.cs b/mcs/tests/dlls/test-939-1/test-939-lib.cs
new file mode 100644 (file)
index 0000000..1351652
--- /dev/null
@@ -0,0 +1,9 @@
+[assembly:System.Reflection.AssemblyVersionAttribute ("2.1.0.0")]
+
+public class Common
+{
+       public static void Foo ()
+       {
+
+       }
+}
diff --git a/mcs/tests/dlls/test-939-1/test-939-ref.cs b/mcs/tests/dlls/test-939-1/test-939-ref.cs
new file mode 100644 (file)
index 0000000..580d407
--- /dev/null
@@ -0,0 +1,10 @@
+[assembly:System.Reflection.AssemblyVersionAttribute ("4.0.0.0")]
+
+public class A : Common
+{
+}
+
+public class B
+{
+       
+}
diff --git a/mcs/tests/dlls/test-939-2/test-939-lib.cs b/mcs/tests/dlls/test-939-2/test-939-lib.cs
new file mode 100644 (file)
index 0000000..b660068
--- /dev/null
@@ -0,0 +1,5 @@
+using System.Runtime.CompilerServices;
+
+[assembly:System.Reflection.AssemblyVersionAttribute ("2.0.0.0")]
+
+[assembly:TypeForwardedTo (typeof (Common))]
diff --git a/mcs/tests/dlls/test-939-common.cs b/mcs/tests/dlls/test-939-common.cs
new file mode 100644 (file)
index 0000000..a6420bb
--- /dev/null
@@ -0,0 +1,9 @@
+[assembly:System.Reflection.AssemblyVersionAttribute ("1.0.0.0")]
+
+public class Common
+{
+       public static void Foo ()
+       {
+
+       }
+}
diff --git a/mcs/tests/test-939.cs b/mcs/tests/test-939.cs
new file mode 100644 (file)
index 0000000..7d83ddf
--- /dev/null
@@ -0,0 +1,14 @@
+// Compiler options: -r:dlls/test-939-1/test-939-ref.dll -r:dlls/test-939-2/test-939-lib.dll -r:dlls/test-939-common.dll
+
+class X
+{
+       public static void Main ()
+       {
+       }
+
+       static void RealTest ()
+       {
+               A.Foo ();
+               new B ();
+       }
+}
\ No newline at end of file
index c705efa9a031fbfcd360998fccab5c8d635e52ed..91d6a9d8ebc90c7e539b470ceaa398ba61822b84 100644 (file)
       </method>
     </type>
   </test>
+  <test name="test-939.cs">
+    <type name="X">
+      <method name="Void Main()" attrs="150">
+        <size>2</size>
+      </method>
+      <method name="Void RealTest()" attrs="145">
+        <size>13</size>
+      </method>
+      <method name="Void .ctor()" attrs="6278">
+        <size>7</size>
+      </method>
+    </type>
+  </test>
   <test name="test-94.cs">
     <type name="Base">
       <method name="Int32 IVehicle.Start()" attrs="481">