Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/linker.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/error-codes.md4
-rw-r--r--src/linker/Linker/Driver.cs20
-rw-r--r--src/linker/Linker/LinkContext.cs57
-rw-r--r--src/linker/Linker/MessageCategory.cs4
-rw-r--r--src/linker/Linker/MessageContainer.cs47
-rw-r--r--src/linker/ref/Linker/MessageContainer.cs4
-rw-r--r--test/ILLink.Tasks.Tests/ILLink.Tasks.Tests.cs28
-rw-r--r--test/Mono.Linker.Tests.Cases/Warnings/NoWarnRegardlessOfWarnAsError.cs29
-rw-r--r--test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/CanGenerateWarningSuppressionFileXml.cs3
-rw-r--r--test/Mono.Linker.Tests/Tests/MessageContainerTests.cs2
10 files changed, 108 insertions, 90 deletions
diff --git a/docs/error-codes.md b/docs/error-codes.md
index 8fb7833b8..d654257a4 100644
--- a/docs/error-codes.md
+++ b/docs/error-codes.md
@@ -113,6 +113,10 @@ the error code. For example:
#### `IL1030`: Invalid argument for '{token}' option
+#### `IL1031`: "Invalid value 'value' was used as warning code
+
+- All warning codes must start with `IL` prefix followed by numeric code.
+
----
## Warning Codes
diff --git a/src/linker/Linker/Driver.cs b/src/linker/Linker/Driver.cs
index b2e402fbd..78da74298 100644
--- a/src/linker/Linker/Driver.cs
+++ b/src/linker/Linker/Driver.cs
@@ -444,14 +444,14 @@ namespace Mono.Linker
if (!GetStringParam (token, l => noWarnArgument = l))
return -1;
- context.NoWarn.UnionWith (ParseWarnings (noWarnArgument));
+ context.NoWarn.UnionWith (ProcessWarningCodes (noWarnArgument));
continue;
case "--warnaserror":
case "--warnaserror+":
var warningList = GetNextStringValue ();
if (!string.IsNullOrEmpty (warningList)) {
- foreach (var warning in ParseWarnings (warningList))
+ foreach (var warning in ProcessWarningCodes (warningList))
context.WarnAsError[warning] = true;
} else {
@@ -464,7 +464,7 @@ namespace Mono.Linker
case "--warnaserror-":
warningList = GetNextStringValue ();
if (!string.IsNullOrEmpty (warningList)) {
- foreach (var warning in ParseWarnings (warningList))
+ foreach (var warning in ProcessWarningCodes (warningList))
context.WarnAsError[warning] = false;
} else {
@@ -775,7 +775,7 @@ namespace Mono.Linker
partial void PreProcessPipeline (Pipeline pipeline);
- private static HashSet<uint> ParseWarnings (string value)
+ private IEnumerable<int> ProcessWarningCodes (string value)
{
string Unquote (string arg)
{
@@ -787,18 +787,14 @@ namespace Mono.Linker
value = Unquote (value);
string[] values = value.Split (new char[] { ',', ';', ' ' }, StringSplitOptions.RemoveEmptyEntries);
- HashSet<uint> warningCodes = new HashSet<uint> ();
foreach (string id in values) {
- if (!id.StartsWith ("IL", StringComparison.Ordinal))
+ if (!id.StartsWith ("IL", StringComparison.Ordinal) || !ushort.TryParse (id.Substring (2), out ushort code)) {
+ context.LogError ($"Invalid value '{id}' was used as warning code", 1031);
continue;
+ }
- var warningCode = id.Substring (2);
- if (ushort.TryParse (warningCode, out ushort code)
- && code > 2000 && code <= 6000)
- warningCodes.Add (code);
+ yield return code;
}
-
- return warningCodes;
}
Assembly GetCustomAssembly (string arg)
diff --git a/src/linker/Linker/LinkContext.cs b/src/linker/Linker/LinkContext.cs
index 331f51ba9..55f2e901a 100644
--- a/src/linker/Linker/LinkContext.cs
+++ b/src/linker/Linker/LinkContext.cs
@@ -174,9 +174,9 @@ namespace Mono.Linker
public WarningSuppressionWriter WarningSuppressionWriter { get; private set; }
- public HashSet<uint> NoWarn { get; set; }
+ public HashSet<int> NoWarn { get; set; }
- public Dictionary<uint, bool> WarnAsError { get; set; }
+ public Dictionary<int, bool> WarnAsError { get; set; }
public bool GeneralWarnAsError { get; set; }
@@ -236,9 +236,9 @@ namespace Mono.Linker
StripLinkAttributes = true;
PInvokes = new List<PInvokeInfo> ();
Suppressions = new UnconditionalSuppressMessageAttributeState (this);
- NoWarn = new HashSet<uint> ();
+ NoWarn = new HashSet<int> ();
GeneralWarnAsError = false;
- WarnAsError = new Dictionary<uint, bool> ();
+ WarnAsError = new Dictionary<int, bool> ();
WarnVersion = WarnVersion.Latest;
// See https://github.com/mono/linker/issues/612
@@ -502,22 +502,9 @@ namespace Mono.Linker
message.Category == MessageCategory.Info) && !LogMessages)
return;
- if (message.Category == MessageCategory.Warning &&
- NoWarn.Contains ((uint) message.Code)) {
- // This warning was turned off by --nowarn.
- return;
- }
-
- // Note: message.Version is nullable. The comparison is false if it is null.
- // Unversioned warnings are not controlled by WarnVersion.
- // Error messages are guaranteed to only have a version if they were created for a warning due to warnaserror.
- if ((message.Category == MessageCategory.Warning || message.Category == MessageCategory.Error) &&
- message.Version > WarnVersion) {
- // This warning was turned off by --warn.
- return;
- }
-
- if (OutputWarningSuppressions && message.Category == MessageCategory.Warning && message.Origin?.MemberDefinition != null)
+ if (OutputWarningSuppressions &&
+ (message.Category == MessageCategory.Warning || message.Category == MessageCategory.WarningAsError) &&
+ message.Origin?.MemberDefinition != null)
WarningSuppressionWriter.AddWarning (message.Code.Value, message.Origin?.MemberDefinition);
Logger?.LogMessage (message);
@@ -552,15 +539,8 @@ namespace Mono.Linker
/// <returns>New MessageContainer of 'Warning' category</returns>
public void LogWarning (string text, int code, MessageOrigin origin, string subcategory = MessageSubCategory.None)
{
- var version = GetWarningVersion (code);
-
- if ((GeneralWarnAsError && (!WarnAsError.TryGetValue ((uint) code, out var warnAsError) || warnAsError)) ||
- (!GeneralWarnAsError && (WarnAsError.TryGetValue ((uint) code, out warnAsError) && warnAsError))) {
- LogError (text, code, subcategory, origin, isWarnAsError: true, version: version);
- return;
- }
-
- var warning = MessageContainer.CreateWarningMessage (this, text, code, origin, subcategory, version);
+ WarnVersion version = GetWarningVersion (code);
+ MessageContainer warning = MessageContainer.CreateWarningMessage (this, text, code, origin, version, subcategory);
LogMessage (warning);
}
@@ -604,21 +584,34 @@ namespace Mono.Linker
/// <param name="subcategory">Optionally, further categorize this error</param>
/// <param name="origin">Filename, line, and column where the error was found</param>
/// <returns>New MessageContainer of 'Error' category</returns>
- public void LogError (string text, int code, string subcategory = MessageSubCategory.None, MessageOrigin? origin = null, bool isWarnAsError = false, WarnVersion? version = null)
+ public void LogError (string text, int code, string subcategory = MessageSubCategory.None, MessageOrigin? origin = null)
{
- var error = MessageContainer.CreateErrorMessage (text, code, subcategory, origin, isWarnAsError, version);
+ var error = MessageContainer.CreateErrorMessage (text, code, subcategory, origin);
LogMessage (error);
}
public bool IsWarningSuppressed (int warningCode, MessageOrigin origin)
{
+ // This warning was turned off by --nowarn.
+ if (NoWarn.Contains (warningCode))
+ return true;
+
if (Suppressions == null)
return false;
return Suppressions.IsSuppressed (warningCode, origin, out _);
}
- public static WarnVersion GetWarningVersion (int code)
+ public bool IsWarningAsError (int warningCode)
+ {
+ bool value;
+ if (GeneralWarnAsError)
+ return !WarnAsError.TryGetValue (warningCode, out value) || value;
+
+ return WarnAsError.TryGetValue (warningCode, out value) && value;
+ }
+
+ static WarnVersion GetWarningVersion (int code)
{
// This should return an increasing WarnVersion for new warning waves.
return WarnVersion.ILLink5;
diff --git a/src/linker/Linker/MessageCategory.cs b/src/linker/Linker/MessageCategory.cs
index f0cf092f8..1ca1a1085 100644
--- a/src/linker/Linker/MessageCategory.cs
+++ b/src/linker/Linker/MessageCategory.cs
@@ -9,6 +9,8 @@ namespace Mono.Linker
Error = 0,
Warning,
Info,
- Diagnostic
+ Diagnostic,
+
+ WarningAsError = 0xFF
}
}
diff --git a/src/linker/Linker/MessageContainer.cs b/src/linker/Linker/MessageContainer.cs
index f0149546a..fd81f732a 100644
--- a/src/linker/Linker/MessageContainer.cs
+++ b/src/linker/Linker/MessageContainer.cs
@@ -31,10 +31,6 @@ namespace Mono.Linker
public int? Code { get; }
/// <summary>
- /// Version number for this warning.
- public WarnVersion? Version { get; }
-
- /// <summary>
/// User friendly text describing the error or warning.
/// </summary>
public string Text { get; }
@@ -48,18 +44,12 @@ namespace Mono.Linker
/// <param name="subcategory">Optionally, further categorize this error</param>
/// <param name="origin">Filename, line, and column where the error was found</param>
/// <returns>New MessageContainer of 'Error' category</returns>
- public static MessageContainer CreateErrorMessage (string text, int code, string subcategory = MessageSubCategory.None, MessageOrigin? origin = null, bool isWarnAsError = false, WarnVersion? version = null)
+ public static MessageContainer CreateErrorMessage (string text, int code, string subcategory = MessageSubCategory.None, MessageOrigin? origin = null)
{
- if (isWarnAsError) {
- ValidateWarning (code, version);
- } else {
- if (!(code >= 1000 && code <= 2000))
- throw new ArgumentException ($"The provided code '{code}' does not fall into the error category, which is in the range of 1000 to 2000 (inclusive).");
- if (version != null)
- throw new ArgumentException ($"An error message may not have a version.");
- }
+ if (!(code >= 1000 && code <= 2000))
+ throw new ArgumentException ($"The provided code '{code}' does not fall into the error category, which is in the range of 1000 to 2000 (inclusive).");
- return new MessageContainer (MessageCategory.Error, text, code, subcategory, origin, version);
+ return new MessageContainer (MessageCategory.Error, text, code, subcategory, origin);
}
/// <summary>
@@ -74,14 +64,24 @@ namespace Mono.Linker
/// <param name="version">Optional warning version number. Versioned warnings can be controlled with the
/// warning wave option --warn VERSION. Unversioned warnings are unaffected by this option. </param>
/// <returns>New MessageContainer of 'Warning' category</returns>
- public static MessageContainer CreateWarningMessage (LinkContext context, string text, int code, MessageOrigin origin, string subcategory = MessageSubCategory.None, WarnVersion? version = null)
+ public static MessageContainer CreateWarningMessage (LinkContext context, string text, int code, MessageOrigin origin, WarnVersion version, string subcategory = MessageSubCategory.None)
{
- ValidateWarning (code, version);
+ if (!(code > 2000 && code <= 6000))
+ throw new ArgumentException ($"The provided code '{code}' does not fall into the warning category, which is in the range of 2001 to 6000 (inclusive).");
+
+ if (!(version >= WarnVersion.ILLink0 && version <= WarnVersion.Latest))
+ throw new ArgumentException ($"The provided warning version '{version}' is invalid.");
if (context.IsWarningSuppressed (code, origin))
return Empty;
- return new MessageContainer (MessageCategory.Warning, text, code, subcategory, origin, version);
+ if (version > context.WarnVersion)
+ return Empty;
+
+ if (context.IsWarningAsError (code))
+ return new MessageContainer (MessageCategory.WarningAsError, text, code, subcategory, origin);
+
+ return new MessageContainer (MessageCategory.Warning, text, code, subcategory, origin);
}
/// <summary>
@@ -104,23 +104,13 @@ namespace Mono.Linker
return new MessageContainer (MessageCategory.Diagnostic, text, null);
}
- private MessageContainer (MessageCategory category, string text, int? code, string subcategory = MessageSubCategory.None, MessageOrigin? origin = null, WarnVersion? version = null)
+ private MessageContainer (MessageCategory category, string text, int? code, string subcategory = MessageSubCategory.None, MessageOrigin? origin = null)
{
Code = code;
Category = category;
Origin = origin;
SubCategory = subcategory;
Text = text;
- Version = version;
- }
-
- static void ValidateWarning (int code, WarnVersion? version)
- {
- if (!(code > 2000 && code <= 6000))
- throw new ArgumentException ($"The provided code '{code}' does not fall into the warning category, which is in the range of 2001 to 6000 (inclusive).");
-
- if (version != null && !(version >= WarnVersion.ILLink0 && version <= WarnVersion.Latest))
- throw new ArgumentException ($"The provided warning version '{version}' is invalid.");
}
public override string ToString () => ToMSBuildString ();
@@ -139,6 +129,7 @@ namespace Mono.Linker
string cat;
switch (Category) {
case MessageCategory.Error:
+ case MessageCategory.WarningAsError:
cat = "error";
break;
case MessageCategory.Warning:
diff --git a/src/linker/ref/Linker/MessageContainer.cs b/src/linker/ref/Linker/MessageContainer.cs
index e9b6ad9f4..11427d317 100644
--- a/src/linker/ref/Linker/MessageContainer.cs
+++ b/src/linker/ref/Linker/MessageContainer.cs
@@ -6,8 +6,8 @@ namespace Mono.Linker
{
public readonly struct MessageContainer
{
- public static MessageContainer CreateErrorMessage (string text, int code, string subcategory = "", MessageOrigin? origin = null, bool isWarnAsError = false, WarnVersion? version = null) { throw null; }
- public static MessageContainer CreateWarningMessage (LinkContext context, string text, int code, MessageOrigin origin, string subcategory = "", WarnVersion? version = null) { throw null; }
+ public static MessageContainer CreateErrorMessage (string text, int code, string subcategory = "", MessageOrigin? origin = null) { throw null; }
+ public static MessageContainer CreateWarningMessage (LinkContext context, string text, int code, MessageOrigin origin, WarnVersion version, string subcategory = "") { throw null; }
public static MessageContainer CreateInfoMessage (string text) { throw null; }
public static MessageContainer CreateDiagnosticMessage (string text) { throw null; }
}
diff --git a/test/ILLink.Tasks.Tests/ILLink.Tasks.Tests.cs b/test/ILLink.Tasks.Tests/ILLink.Tasks.Tests.cs
index 77162f574..3223ab5ae 100644
--- a/test/ILLink.Tasks.Tests/ILLink.Tasks.Tests.cs
+++ b/test/ILLink.Tasks.Tests/ILLink.Tasks.Tests.cs
@@ -273,9 +273,9 @@ namespace ILLink.Tasks.Tests
[InlineData ("IL2001;IL2002;IL2003;IL2004", 4)]
[InlineData ("IL2001 IL2002 IL2003 IL2004", 4)]
[InlineData ("IL2001,IL2002,IL2003,IL2004", 4)]
- [InlineData ("IL2001,IL2002; IL2003 IL2004", 4)]
- [InlineData ("IL2001,CS4550,CA2123,IL2002,2000,IL8000,IL1003", 2)]
- [InlineData ("SomeText,IL20000,IL02000", 0)]
+ [InlineData ("IL2001,IL2002;IL2003 IL2004", 4)]
+ [InlineData ("IL2001,IL2002,IL8000,IL1003", 4)]
+ [InlineData ("IL20000,IL02000", 2)]
public void TestValidNoWarn (string noWarn, int validNoWarns)
{
var task = new MockTask () {
@@ -304,16 +304,16 @@ namespace ILLink.Tasks.Tests
#nullable enable
[Theory]
- [InlineData (true, null, null, new uint[] { }, new uint[] { })]
- [InlineData (false, "IL1001,IL####,IL2000,IL2054,IL2022", null,
- new uint[] { 2054, 2022 }, new uint[] { })]
+ [InlineData (true, null, null, new int[] { }, new int[] { })]
+ [InlineData (false, "IL1001,IL2000,IL2054,IL2022", null,
+ new int[] { 1001, 2000, 2054, 2022 }, new int[] { })]
[InlineData (false, "IL2023,IL6000;IL5042 IL2040", "IL4000,IL4001;IL4002 IL4003",
- new uint[] { 2023, 2040, 5042, 6000 }, new uint[] { 4000, 4001, 4002, 4003 })]
- [InlineData (false, "IL3000;IL3000;ABCD", "IL2005 il3000 IL2005",
- new uint[] { 3000 }, new uint[] { 2005 })]
- [InlineData (true, null, "IL2067", new uint[] { }, new uint[] { 2067 })]
- [InlineData (true, "IL2001", "IL2001", new uint[] { }, new uint[] { 2001 })]
- public void TestWarningsAsErrors (bool treatWarningsAsErrors, string? warningsAsErrors, string? warningsNotAsErrors, uint[] warnAsError, uint[] warnNotAsError)
+ new int[] { 2023, 2040, 5042, 6000 }, new int[] { 4000, 4001, 4002, 4003 })]
+ [InlineData (false, "IL3000;IL3000;ABCD", "IL2005 IL3005 IL2005",
+ new int[] { 3000 }, new int[] { 2005, 3005 })]
+ [InlineData (true, null, "IL2067", new int[] { }, new int[] { 2067 })]
+ [InlineData (true, "IL2001", "IL2001", new int[] { }, new int[] { 2001 })]
+ public void TestWarningsAsErrors (bool treatWarningsAsErrors, string? warningsAsErrors, string? warningsNotAsErrors, int[] warnAsError, int[] warnNotAsError)
{
var task = new MockTask () {
TreatWarningsAsErrors = treatWarningsAsErrors,
@@ -324,8 +324,8 @@ namespace ILLink.Tasks.Tests
using (var driver = task.CreateDriver ()) {
var actualWarnAsError = driver.Context.WarnAsError;
var actualGeneralWarnAsError = driver.Context.GeneralWarnAsError;
- Assert.Equal (actualWarnAsError.Count, warnAsError.Distinct ().Count () + warnNotAsError.Distinct ().Count ());
- Assert.Equal (actualGeneralWarnAsError, treatWarningsAsErrors);
+ Assert.Equal (warnAsError.Count () + warnNotAsError.Count (), actualWarnAsError.Count);
+ Assert.Equal (treatWarningsAsErrors, actualGeneralWarnAsError);
if (warnAsError.Length > 0) {
foreach (var warningCode in warnAsError)
Assert.True (actualWarnAsError.ContainsKey (warningCode) && actualWarnAsError[warningCode] == true);
diff --git a/test/Mono.Linker.Tests.Cases/Warnings/NoWarnRegardlessOfWarnAsError.cs b/test/Mono.Linker.Tests.Cases/Warnings/NoWarnRegardlessOfWarnAsError.cs
new file mode 100644
index 000000000..dc49c24a6
--- /dev/null
+++ b/test/Mono.Linker.Tests.Cases/Warnings/NoWarnRegardlessOfWarnAsError.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics.CodeAnalysis;
+using System.Text;
+using Mono.Linker.Tests.Cases.Expectations.Assertions;
+using Mono.Linker.Tests.Cases.Expectations.Metadata;
+
+namespace Mono.Linker.Tests.Cases.Warnings
+{
+ [SkipKeptItemsValidation]
+ [SetupLinkerArgument ("--warnaserror")]
+ [SetupLinkerArgument ("--nowarn", "IL2006")]
+ [LogDoesNotContain ("IL2006")]
+ public class NoWarnRegardlessOfWarnAsError
+ {
+ public static void Main ()
+ {
+ GetMethod ();
+ }
+
+ [DynamicallyAccessedMembers (DynamicallyAccessedMemberTypes.PublicFields)]
+ static string type;
+
+ static void GetMethod ()
+ {
+ _ = Type.GetType (type).GetMethod ("Foo");
+ }
+ }
+} \ No newline at end of file
diff --git a/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/CanGenerateWarningSuppressionFileXml.cs b/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/CanGenerateWarningSuppressionFileXml.cs
index b0bb6f72e..55bf0418f 100644
--- a/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/CanGenerateWarningSuppressionFileXml.cs
+++ b/test/Mono.Linker.Tests.Cases/Warnings/WarningSuppression/CanGenerateWarningSuppressionFileXml.cs
@@ -14,6 +14,9 @@ namespace Mono.Linker.Tests.Cases.Warnings.WarningSuppression
[SetupLinkerAction ("link", "library.dll")]
[SetupLinkerArgument ("--verbose")]
[SetupLinkerArgument ("--generate-warning-suppressions", "xml")]
+
+ // Test that --warnaserror has no effect on --generate-warning-suppressions
+ [SetupLinkerArgument ("--warnaserror")]
public class CanGenerateWarningSuppressionFileXml
{
public static void Main ()
diff --git a/test/Mono.Linker.Tests/Tests/MessageContainerTests.cs b/test/Mono.Linker.Tests/Tests/MessageContainerTests.cs
index a6969b245..63765312b 100644
--- a/test/Mono.Linker.Tests/Tests/MessageContainerTests.cs
+++ b/test/Mono.Linker.Tests/Tests/MessageContainerTests.cs
@@ -13,7 +13,7 @@ namespace Mono.Linker.Tests
var msg = MessageContainer.CreateErrorMessage ("text", 1000);
Assert.AreEqual ("ILLink: error IL1000: text", msg.ToMSBuildString ());
- msg = MessageContainer.CreateWarningMessage (context, "message", 2001, new MessageOrigin ("logtest", 1, 1));
+ msg = MessageContainer.CreateWarningMessage (context, "message", 2001, new MessageOrigin ("logtest", 1, 1), WarnVersion.Latest);
Assert.AreEqual ("logtest(1,1): warning IL2001: message", msg.ToMSBuildString ());
msg = MessageContainer.CreateInfoMessage ("log test");