Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IL verification with ILVerify in addition to PEVerify #37994

Merged
merged 54 commits into from
Feb 11, 2022
Merged
Show file tree
Hide file tree
Changes from 53 commits
Commits
Show all changes
54 commits
Select commit Hold shift + click to select a range
d1e402c
Add IL verification with ILVerify in addition to PEVerify
jcouv Nov 2, 2017
70d3ab8
Annotating more tests
jcouv Mar 22, 2018
3f8b70f
Use new package with strong name
jcouv Mar 22, 2018
6e2efce
Merge remote-tracking branch 'dotnet/main' into il-verify2
jcouv Dec 30, 2021
bf116d9
Fix a couple more tests
jcouv Dec 30, 2021
a993d0e
Address some PROTOTYPE markers
jcouv Dec 30, 2021
7af8ecc
Tighten checks
jcouv Dec 30, 2021
0ee5f6a
Fix IL verification plumbing
jcouv Dec 30, 2021
1701dbb
Transition ILVerify to Core test runner
jcouv Dec 31, 2021
260a40e
Fix Resolver
jcouv Dec 31, 2021
7b0263a
public
jcouv Dec 31, 2021
400d315
Start tightening the IL verification
jcouv Dec 31, 2021
e7a7c3f
Remove some unused error entries
jcouv Dec 31, 2021
9cafb53
Annotate failures
jcouv Dec 31, 2021
656d328
InitOnly and NotVisible
jcouv Jan 1, 2022
eea70d3
MissingStringType
jcouv Jan 1, 2022
d328e27
MissingAssembly
jcouv Jan 1, 2022
ebbc74a
BadReturnType
jcouv Jan 1, 2022
66aa35b
More
jcouv Jan 1, 2022
c34aa28
More
jcouv Jan 1, 2022
d23c09c
Change design of flags
jcouv Jan 1, 2022
5a01e58
Ctor
jcouv Jan 1, 2022
ae83e16
more
jcouv Jan 2, 2022
9b1260c
more
jcouv Jan 2, 2022
ec54177
tweak
jcouv Jan 2, 2022
99e0f0a
VB
jcouv Jan 2, 2022
b2fc7c7
Conditional package reference
jcouv Jan 3, 2022
ebacf4f
Remove tracking of specific failures
jcouv Jan 5, 2022
d57946e
Move check
jcouv Jan 5, 2022
a345b1b
VB
jcouv Jan 5, 2022
7abba2e
Undo some changes
jcouv Jan 5, 2022
f3a3859
Cleanup
jcouv Jan 5, 2022
262ee1e
Refine resolution of ambiguities
jcouv Jan 6, 2022
733ac37
Align on simple names
jcouv Jan 6, 2022
c1f0f8d
Use signed ILVerification package from dotnet7 feed
jcouv Jan 29, 2022
f193504
Enable on desktop runtime
jcouv Jan 29, 2022
fffe57a
Merge remote-tracking branch 'dotnet/main' into il-verify2
jcouv Jan 29, 2022
4cf0b49
Revert "Enable on desktop runtime"
jcouv Jan 29, 2022
dceda42
Update added tests
jcouv Jan 29, 2022
115da8a
Use compilation to identify corlib
jcouv Jan 31, 2022
af67143
Use label for version number
jcouv Jan 31, 2022
a7dc694
Address feedback
jcouv Feb 2, 2022
ca5027f
Address feedback
jcouv Feb 8, 2022
6d83957
usings
jcouv Feb 8, 2022
c7d7ba6
Rename
jcouv Feb 8, 2022
cb27c93
indentation
jcouv Feb 8, 2022
a11ad37
Merge remote-tracking branch 'dotnet/main' into il-verify2
jcouv Feb 8, 2022
e32bf0a
Resolve conflicts
jcouv Feb 8, 2022
7e0ec94
remove catch
jcouv Feb 9, 2022
f5387f8
Revert "remove catch"
jcouv Feb 9, 2022
f9cf399
Shrink usage of exceptions
jcouv Feb 9, 2022
c55a61d
Adjust to new logic
jcouv Feb 9, 2022
fcc2dc2
one more test
jcouv Feb 10, 2022
3db3d54
Address feedback
jcouv Feb 10, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NuGet.config
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
<add key="dotnet-tools" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-tools/nuget/v3/index.json" />
<add key="dotnet5" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet5/nuget/v3/index.json" />
<add key="dotnet6" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet6/nuget/v3/index.json" />
<add key="dotnet7" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet7/nuget/v3/index.json" />
<add key="dotnet-public" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public/nuget/v3/index.json" />
<add key="nuget-build" value="https://pkgs.dev.azure.com/dnceng/public/_packaging/nuget-build/nuget/v3/index.json" />
<add key="vssdk" value="https://pkgs.dev.azure.com/azure-public/vside/_packaging/vssdk/nuget/v3/index.json" />
Expand Down
1 change: 1 addition & 0 deletions eng/Versions.props
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
but not higher than our minimum dogfoodable Visual Studio version, or else
the generators we build would load on the command line but not load in IDEs. -->
<SourceGeneratorMicrosoftCodeAnalysisVersion>3.8.0</SourceGeneratorMicrosoftCodeAnalysisVersion>
<MicrosoftILVerificationVersion>7.0.0-alpha.1.22060.1</MicrosoftILVerificationVersion>
</PropertyGroup>
<!--
Dependency versions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6161,7 +6161,7 @@ public static async IAsyncEnumerator<int> GetAsyncEnumerator(this Range range)
options: TestOptions.DebugExe,
parseOptions: TestOptions.Regular9);
comp.VerifyDiagnostics();
CompileAndVerify(comp, expectedOutput: "123");
CompileAndVerify(comp, expectedOutput: "123", verify: Verification.FailsILVerify);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7614,7 +7614,7 @@ static void Main()
}

[Fact]
void InvokeVarForLvalueInParens()
public void InvokeVarForLvalueInParens()
{
var source = @"
class Program
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9603,7 +9603,7 @@ .locals init (int V_0, //a
IL_0066: callvirt ""void <>A{00000004}<System.Runtime.CompilerServices.CallSite, int, object>.Invoke(System.Runtime.CompilerServices.CallSite, ref int, object)""
IL_006b: ret
}
");
", verify: Verification.FailsILVerify); // ILVerify doesn't support TypedReference
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3117,9 +3117,10 @@ public static void Main()
}
}";

// PEVerify: [ : Test::Main][mdToken=0x6000001][offset 0x00000009][found Native Int][expected unmanaged pointer] Unexpected type on the stack.
jaredpar marked this conversation as resolved.
Show resolved Hide resolved
var c = CompileAndVerifyUtil(text,
options: TestOptions.UnsafeReleaseDll,
verify: Verification.Fails);
verify: Verification.FailsPEVerify);

c.VerifyDiagnostics();
}
Expand Down
27 changes: 18 additions & 9 deletions src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenForEachTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1384,7 +1384,8 @@ ref struct DisposableEnumerator
public bool MoveNext() { return ++x < 4; }
public void Dispose() { System.Console.WriteLine(""Done with DisposableEnumerator""); }
}";
var compilation = CompileAndVerify(source, expectedOutput: @"
// ILVerify: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
var compilation = CompileAndVerify(source, verify: Verification.FailsILVerify, expectedOutput: @"
1
2
3
Expand Down Expand Up @@ -1447,7 +1448,8 @@ ref struct DisposableEnumerator
public bool MoveNext() { return ++x < 4; }
public void Dispose(params object[] args) { System.Console.WriteLine($""Done with DisposableEnumerator. args was {args}, length {args.Length}""); }
}";
var compilation = CompileAndVerify(source, expectedOutput: @"
// ILVerify: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
var compilation = CompileAndVerify(source, verify: Verification.FailsILVerify, expectedOutput: @"
1
2
3
Expand Down Expand Up @@ -1481,7 +1483,8 @@ ref struct DisposableEnumerator
public bool MoveNext() { return ++x < 4; }
public void Dispose(int arg = 1) { System.Console.WriteLine($""Done with DisposableEnumerator. arg was {arg}""); }
}";
var compilation = CompileAndVerify(source, expectedOutput: @"
// ILVerify: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
var compilation = CompileAndVerify(source, verify: Verification.FailsILVerify, expectedOutput: @"
1
2
3
Expand Down Expand Up @@ -1521,7 +1524,8 @@ static class DisposeExtension
}
";
// extension methods do not contribute to disposal
CompileAndVerify(source, expectedOutput: @"123");
// ILVerify: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
CompileAndVerify(source, verify: Verification.FailsILVerify, expectedOutput: @"123");
}

[Fact]
Expand Down Expand Up @@ -1561,7 +1565,8 @@ static class DisposeExtension2
}
";
// extension methods do not contribute to disposal
CompileAndVerify(source, expectedOutput: @"123");
// ILVerify: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
CompileAndVerify(source, verify: Verification.FailsILVerify, expectedOutput: @"123");
}

[Fact]
Expand Down Expand Up @@ -1597,7 +1602,8 @@ static class DisposeExtension
}
";
// extension methods do not contribute to disposal
CompileAndVerify(source, expectedOutput: @"123");
// ILVerify: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
CompileAndVerify(source, verify: Verification.FailsILVerify, expectedOutput: @"123");
}

[Fact]
Expand Down Expand Up @@ -1633,7 +1639,8 @@ static class DisposeExtension
}
";
// extension methods do not contribute to disposal
CompileAndVerify(source, expectedOutput: @"123");
// ILVerify: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
CompileAndVerify(source, verify: Verification.FailsILVerify, expectedOutput: @"123");
}

[Fact]
Expand Down Expand Up @@ -1729,7 +1736,8 @@ ref struct DisposableEnumerator
public bool MoveNext() { return ++x < 4; }
public void Dispose() { System.Console.WriteLine(""Done with DisposableEnumerator""); }
}";
var compilation = CompileAndVerify(source, parseOptions: TestOptions.Regular7_3, expectedOutput: @"
// ILVerify: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
var compilation = CompileAndVerify(source, parseOptions: TestOptions.Regular7_3, verify: Verification.FailsILVerify, expectedOutput: @"
1
2
3");
Expand Down Expand Up @@ -4725,7 +4733,8 @@ ref struct Enumerator
public bool MoveNext() => Current++ != 3;
public void Dispose() { Console.Write(""Disposed""); }
}";
CompileAndVerify(source, parseOptions: TestOptions.Regular9, expectedOutput: @"123Disposed")
// ILVerify: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
CompileAndVerify(source, parseOptions: TestOptions.Regular9, verify: Verification.FailsILVerify, expectedOutput: @"123Disposed")
.VerifyIL("C.Main", @"
{
// Code size 45 (0x2d)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3982,7 +3982,8 @@ private void Test2(in int y, ref int f)

var compilation = CreateCompilation(code, options: TestOptions.ReleaseExe);

var verifier = CompileAndVerify(compilation, expectedOutput: "0011", verify: Verification.Fails);
// PEVerify: Cannot change initonly field outside its .ctor.
var verifier = CompileAndVerify(compilation, expectedOutput: "0011", verify: Verification.FailsPEVerify);

verifier.VerifyIL("Test..ctor()", @"
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using System;
using System.Globalization;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Test.Utilities;
using Roslyn.Test.Utilities;
using Xunit;

Expand Down Expand Up @@ -1033,7 +1034,7 @@ public static void Main()
}
}
";
base.CompileAndVerify(source, expectedOutput: "12").
base.CompileAndVerify(source, verify: Verification.FailsILVerify, expectedOutput: "12").
VerifyIL("Test.Main",
@"
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2387,7 +2387,8 @@ public System.Collections.IEnumerable SomeNumbers()
}";
// The compilation succeeds even though CompilerGeneratedAttribute and DebuggerNonUserCodeAttribute are not available.
var compilation = CreateEmptyCompilation(new[] { Parse(source), Parse(corlib) });
var verifier = CompileAndVerify(compilation, verify: Verification.Fails);
// PEVerify: System.Enum must extend System.ValueType.
var verifier = CompileAndVerify(compilation, verify: Verification.FailsPEVerify);
verifier.VerifyDiagnostics(
// warning CS8021: No value for RuntimeMetadataVersion found. No assembly containing System.Object was found nor was a value for RuntimeMetadataVersion specified through options.
Diagnostic(ErrorCode.WRN_NoRuntimeMetadataVersion).WithLocation(1, 1));
Expand Down
8 changes: 8 additions & 0 deletions src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenMscorlib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -744,6 +744,12 @@ void Main()
//IMPORTANT: we should NOT delegate E1.GetHashCode() to int.GetHashCode()
// it is entirely possible that Enum.GetHashCode and int.GetHashCode
// have different implementations

// PEVerify:
// Error: Token 0x02000009 following ELEMENT_TYPE_CLASS (_VALUETYPE) in signature is a ValueType (Class,respectively).
// Error: Token 0x02000009 following ELEMENT_TYPE_CLASS(_VALUETYPE) in signature is a ValueType (Class, respectively).
// Type load failed.
// ILVerify: Failed to load type 'System.String' from assembly ...
CompileAndVerify(comp, verify: Verification.Fails).
VerifyIL("program.Main()",
@"
Expand Down Expand Up @@ -871,6 +877,8 @@ void Main()
// but see the bug see VSW #396011, JIT needs references when loading
// fields of certain clr-ambiguous structs (only possible when building mscorlib)

// PEVerify: Type load failed.
// ILVerify: Failed to load type 'System.String' from assembly ...
CompileAndVerify(comp, verify: Verification.Fails).
VerifyIL("System.IntPtr..ctor(int)", @"
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2557,7 +2557,7 @@ public static void Main()
// from assembly 'Dev10, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'
// is overriding a method that is not visible from that assembly.

CompileAndVerify(outerCompilation, verify: Verification.Fails).VerifyIL("Test.Main", @"
CompileAndVerify(outerCompilation, verify: Verification.FailsPEVerify).VerifyIL("Test.Main", @"
{
// Code size 65 (0x41)
.maxstack 4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ public override string ToString()
}
";

var comp = CompileAndVerify(text, parseOptions: TestOptions.Regular, verify: Verification.Fails, expectedOutput: @"12");
var comp = CompileAndVerify(text, parseOptions: TestOptions.Regular, verify: Verification.FailsPEVerify, expectedOutput: @"12");

comp.VerifyIL("Program.Main", @"
{
Expand Down Expand Up @@ -258,7 +258,8 @@ public override string ToString()
}
";

var comp = CompileAndVerify(text, parseOptions: TestOptions.Regular, verify: Verification.Fails, expectedOutput: @"hello2");
// PEVerify: Cannot change initonly field outside its .ctor.
var comp = CompileAndVerify(text, parseOptions: TestOptions.Regular, verify: Verification.FailsPEVerify, expectedOutput: @"hello2");

comp.VerifyIL("Program.Main", @"
{
Expand Down Expand Up @@ -338,7 +339,8 @@ static void Main()
}
";

var comp = CompileAndVerify(text, new[] { ref1 }, parseOptions: TestOptions.Regular, verify: Verification.Fails, expectedOutput: @"hello2");
// PEVerify: Cannot change initonly field outside its .ctor.
var comp = CompileAndVerify(text, new[] { ref1 }, parseOptions: TestOptions.Regular, verify: Verification.FailsPEVerify, expectedOutput: @"hello2");

comp.VerifyIL("Program.Main", @"
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1060,7 +1060,8 @@ public static void RoExtension(in this S1 self)
}
";

var comp = CompileAndVerifyWithMscorlib40(source, references: new[] { TestMetadata.Net40.System, ValueTupleRef, TestMetadata.Net40.SystemCore }, expectedOutput: "00", verify: Verification.Fails);
// PEVerify: Cannot change initonly field outside its .ctor.
var comp = CompileAndVerifyWithMscorlib40(source, references: new[] { TestMetadata.Net40.System, ValueTupleRef, TestMetadata.Net40.SystemCore }, expectedOutput: "00", verify: Verification.FailsPEVerify);
comp.VerifyDiagnostics();

comp.VerifyIL("Program.Main", @"
Expand Down Expand Up @@ -1147,8 +1148,8 @@ public override string ToString()
}
}
";

var comp = CompileAndVerify(source, expectedOutput: "00", verify: Verification.Fails);
// PEVerify: Cannot change initonly field outside its .ctor.
var comp = CompileAndVerify(source, expectedOutput: "00", verify: Verification.FailsPEVerify);
comp.VerifyDiagnostics();

comp.VerifyIL("Program.Test", @"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -554,7 +554,7 @@ public void SubmissionEntryPoint()
"s0.dll",
SyntaxFactory.ParseSyntaxTree(source0, options: TestOptions.Script),
references);
var verifier = CompileAndVerify(s0, verify: Verification.Fails);
var verifier = CompileAndVerify(s0, verify: Verification.FailsPEVerify);
var methodData = verifier.TestData.GetMethodData("<Initialize>");
Assert.Equal("System.Threading.Tasks.Task<object>", ((MethodSymbol)methodData.Method).ReturnType.ToDisplayString());
methodData.VerifyIL(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5233,7 +5233,8 @@ public RefLike M()
public ref struct RefLike{}
}
";
var verifier = CompileAndVerify(source, options: TestOptions.DebugExe.WithAllowUnsafe(true), expectedOutput: @"---
// ILVerify: Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
var verifier = CompileAndVerify(source, verify: Verification.FailsILVerify, options: TestOptions.DebugExe.WithAllowUnsafe(true), expectedOutput: @"---
M
---
---");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -488,10 +488,11 @@ static void Main()
}
}
";
// PEVerify: [ : C::Main][mdToken=0x6000002][offset 0x00000002][found Native Int][expected unmanaged pointer] Unexpected type on the stack.
CompileAndVerify(text,
parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3),
options: TestOptions.UnsafeReleaseExe,
verify: Verification.Fails).VerifyIL("C.Main",
verify: Verification.FailsPEVerify).VerifyIL("C.Main",
@"{
// Code size 8 (0x8)
.maxstack 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -259,7 +259,8 @@ static void Main(string[] args)
}
}
";
var compilation = CompileAndVerify(source, expectedOutput: @"");
// ILVerify: Unexpected type on the stack. { Offset = 20, Found = readonly address of '[...]S1', Expected = address of '[...]S1' }
var compilation = CompileAndVerify(source, verify: Verification.FailsILVerify, expectedOutput: @"");

compilation.VerifyIL("S1.Equals(object)",
@"
Expand Down Expand Up @@ -448,7 +449,8 @@ static void Main()
}
}
";
var compilation = CompileAndVerify(source, expectedOutput: @"
// ILVerify: Unexpected type on the stack. { Offset = 31, Found = readonly address of '[...]NS.N2.S`2<string,uint8>', Expected = address of '[...]NS.N2.S`2<string,uint8>' }
var compilation = CompileAndVerify(source, verify: Verification.FailsILVerify, expectedOutput: @"
Abc
255
q");
Expand Down Expand Up @@ -2365,8 +2367,8 @@ static void Main(string[] args)
}
";

var compilation = CompileAndVerify(source, expectedOutput: "0");
// ILVerify: Unexpected type on the stack. { Offset = 10, Found = readonly address of '[...]C1', Expected = address of '[...]C1' }
var compilation = CompileAndVerify(source, verify: Verification.FailsILVerify, expectedOutput: "0");

compilation.VerifyIL("Program.Main",
@"
Expand Down
Loading