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

[WIP] Add IL verification with ILVerify in addition to PEVerify #25549

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,8 @@ public void MismatchedSurrogateInAssemblyCultureAttribute()
string s = @"[assembly: System.Reflection.AssemblyCultureAttribute(""\uD800"")]";
var comp = CreateCompilation(s, options: TestOptions.ReleaseDll);

CompileAndVerify(comp, verify: Verification.Fails, symbolValidator: m =>
// PROTOTYPE(verification) Can't verify with invalid culture
CompileAndVerify(comp, verify: Verification.Skipped, symbolValidator: m =>
{
var utf8 = new System.Text.UTF8Encoding(false, false);
Assert.Equal(utf8.GetString(utf8.GetBytes("\uD800")), m.ContainingAssembly.Identity.CultureName);
Expand Down Expand Up @@ -539,6 +540,7 @@ void M(Test x) {}
", options: TestOptions.ReleaseDll, references: new[] { hash_module });

CompileAndVerify(compilation,
verify: Verification.PassesPeVerify | Verification.FailsIlVerify, // PROTOTYPE(verification): Unable to resolve token
manifestResources: hash_resources,
validator: (peAssembly) =>
{
Expand Down Expand Up @@ -568,6 +570,7 @@ void M(Test x) {}
", options: TestOptions.ReleaseDll, references: new[] { hash_module });

CompileAndVerify(compilation,
verify: Verification.PassesPeVerify | Verification.FailsIlVerify, // PROTOTYPE(verification): Unable to resolve token
manifestResources: hash_resources,
validator: (peAssembly) =>
{
Expand Down Expand Up @@ -597,6 +600,7 @@ void M(Test x) {}
", options: TestOptions.ReleaseDll, references: new[] { hash_module });

CompileAndVerify(compilation,
verify: Verification.PassesPeVerify | Verification.FailsIlVerify, // PROTOTYPE(verification): Unable to resolve token
manifestResources: hash_resources,
validator: (peAssembly) =>
{
Expand Down Expand Up @@ -626,6 +630,7 @@ void M(Test x) {}
", options: TestOptions.ReleaseDll, references: new[] { hash_module });

CompileAndVerify(compilation,
verify: Verification.PassesPeVerify | Verification.FailsIlVerify, // PROTOTYPE(verification): Unable to resolve token
manifestResources: hash_resources,
validator: (peAssembly) =>
{
Expand Down Expand Up @@ -653,7 +658,7 @@ void M(Test x) {}
}
", options: TestOptions.ReleaseDll, references: new[] { MscorlibRef_v4_0_30316_17626, hash_module });

CompileAndVerify(compilation, verify: Verification.Fails,
CompileAndVerify(compilation, verify: Verification.Skipped,
manifestResources: hash_resources,
validator: (peAssembly) =>
{
Expand Down Expand Up @@ -682,7 +687,7 @@ void M(Test x) {}
}
", options: TestOptions.ReleaseDll, references: new[] { MscorlibRef_v4_0_30316_17626, hash_module });

CompileAndVerify(compilation, verify: Verification.Fails,
CompileAndVerify(compilation, verify: Verification.Skipped,
manifestResources: hash_resources,
validator: (peAssembly) =>
{
Expand Down Expand Up @@ -715,7 +720,7 @@ void M(Test x) {}
}
", options: TestOptions.ReleaseDll, references: new[] { MscorlibRef_v4_0_30316_17626, hash_module });

CompileAndVerify(compilation, verify: Verification.Fails,
CompileAndVerify(compilation, verify: Verification.Skipped,
manifestResources: hash_resources,
validator: (peAssembly) =>
{
Expand Down Expand Up @@ -756,6 +761,7 @@ void M(Test x) {}
", options: TestOptions.ReleaseDll, references: new[] { hash_module_Comp.EmitToImageReference() });

CompileAndVerify(compilation,
verify: Verification.PassesPeVerify | Verification.FailsIlVerify, // PROTOTYPE(verification): Unable to resolve token
validator: (peAssembly) =>
{
var peReader = peAssembly.ManifestModule.GetMetadataReader();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1150,7 +1150,7 @@ static void Main()
comp = CreateEmptyCompilation(source1, references: new[] { ref0, SystemCoreRef });
comp.VerifyDiagnostics();
// Make sure we emit without errors when System.Boolean is missing.
CompileAndVerify(comp, verify: Verification.Fails);
CompileAndVerify(comp, verify: Verification.FailsPeVerify); // PROTOTYPE(verification) Internal.TypeSystem.TypeSystemException+TypeLoadException : [TEMPORARY EXCEPTION MESSAGE] ClassLoadGeneral: System.String, 71b2955e-695c-48f1-86db-7ace51a3dc36, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
}

[Fact]
Expand Down Expand Up @@ -1184,7 +1184,7 @@ static void Main()
comp = CreateEmptyCompilation(source1, references: new[] { ref0, SystemCoreRef });
comp.VerifyDiagnostics();
// Make sure we emit without errors when System.Boolean is missing.
CompileAndVerify(comp, verify: Verification.Fails);
CompileAndVerify(comp, verify: Verification.FailsPeVerify); // PROTOTYPE(verification) Internal.TypeSystem.TypeSystemException+TypeLoadException : [TEMPORARY EXCEPTION MESSAGE] ClassLoadGeneral: System.String, 71b2955e-695c-48f1-86db-7ace51a3dc36, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,8 @@ public class Test
{
public ref struct S1{}
}";

CompileAndVerify(code, verify: Verification.Fails, references: new[] { reference }, options: TestOptions.ReleaseModule, symbolValidator: module =>
// PROTOTYPE(verification)
CompileAndVerify(code, verify: Verification.FailsPeVerify | Verification.PassesIlVerify, references: new[] { reference }, options: TestOptions.ReleaseModule, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("Test").GetTypeMember("S1");

Expand Down Expand Up @@ -953,7 +953,7 @@ public ref struct NotTypedReference { }
}";
var compilation1 = CreateEmptyCompilation(source1, assemblyName: GetUniqueName());

CompileAndVerify(compilation1, verify: Verification.Fails, symbolValidator: module =>
CompileAndVerify(compilation1, verify: Verification.FailsPeVerify, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("System.TypedReference");
AssertReferencedIsByRefLike(type, hasObsolete: false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ public class Test
public void M<T>() where T : unmanaged { }
}
";

CompileAndVerify(text, verify: Verification.Fails, references: new[] { reference }, options: TestOptions.ReleaseModule, symbolValidator: module =>
// PROTOTYPE(verification)
CompileAndVerify(text, verify: Verification.FailsPeVerify | Verification.PassesIlVerify, references: new[] { reference }, options: TestOptions.ReleaseModule, symbolValidator: module =>
{
var typeParameter = module.ContainingAssembly.GetTypeByMetadataName("Test").GetMethod("M").TypeParameters.Single();
Assert.True(typeParameter.HasValueTypeConstraint);
Expand All @@ -160,8 +160,8 @@ public class Test<T> where T : unmanaged
{
}
";

CompileAndVerify(text, verify: Verification.Fails, references: new[] { reference }, options: TestOptions.ReleaseModule, symbolValidator: module =>
// PROTOTYPE(verification)
CompileAndVerify(text, verify: Verification.FailsPeVerify | Verification.PassesIlVerify, references: new[] { reference }, options: TestOptions.ReleaseModule, symbolValidator: module =>
{
var typeParameter = module.ContainingAssembly.GetTypeByMetadataName("Test`1").TypeParameters.Single();
Assert.True(typeParameter.HasValueTypeConstraint);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1153,7 +1153,8 @@ public class Test
public void M(in int x) { }
}";

CompileAndVerify(code, verify: Verification.Fails, references: new[] { reference }, options: TestOptions.ReleaseModule, symbolValidator: module =>
// PROTOTYPE(verification)
CompileAndVerify(code, verify: Verification.FailsPeVerify | Verification.PassesIlVerify, references: new[] { reference }, options: TestOptions.ReleaseModule, symbolValidator: module =>
{
AssertNoIsReadOnlyAttributeExists(module.ContainingAssembly);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -211,10 +211,10 @@ class Structs
};

CompileAndVerify(verifiable, assemblyValidator: validator);
CompileAndVerify(unverifiable, assemblyValidator: validator, verify: Verification.Fails);
CompileAndVerify(unverifiable, assemblyValidator: validator, verify: Verification.ClassLayout);

// CLR limitation on type size, not a RefEmit bug:
CompileAndVerify(unloadable, assemblyValidator: validator, verify: Verification.Fails);
CompileAndVerify(unloadable, assemblyValidator: validator, verify: Verification.ClassLayout);
}

[Fact]
Expand Down Expand Up @@ -332,7 +332,7 @@ public class C : B
}
";
// type C can't be loaded
CompileAndVerify(source, verify: Verification.Fails);
CompileAndVerify(source, verify: Verification.TypeLoadFailed);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -850,7 +850,8 @@ public void MissingWellKnownAttributesNoDiagnosticsAndNoSynthesizedAttributes(Ou
}
else
{
CompileAndVerify(compilation, verify: outputKind.IsNetModule() ? Verification.Skipped : Verification.Passes, symbolValidator: module =>
// PROTOTYPE(verification)
CompileAndVerify(compilation, verify: outputKind.IsNetModule() ? Verification.Skipped : Verification.Skipped, symbolValidator: module =>
{
var assemblyAttributes = module.ContainingAssembly.GetAttributes();
Assert.Equal(0, assemblyAttributes.Length);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3538,7 +3538,7 @@ public static int Main ()

// the resulting code does not need to verify
// This is consistent with Dev10 behavior
CompileAndVerify(source, options: TestOptions.ReleaseDll, verify: Verification.Fails, sourceSymbolValidator: sourceValidator, symbolValidator: metadataValidator);
CompileAndVerify(source, options: TestOptions.ReleaseDll, verify: Verification.UnableToResolveToken, sourceSymbolValidator: sourceValidator, symbolValidator: metadataValidator);
}

[Fact, WorkItem(544507, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544507")]
Expand Down Expand Up @@ -5485,7 +5485,7 @@ public static void Main() {}
// Dev10 Runtime Exception:
// Unhandled Exception: System.TypeLoadException: Windows Runtime types can only be declared in Windows Runtime assemblies.

var verifier = CompileAndVerify(source, sourceSymbolValidator: sourceValidator, symbolValidator: metadataValidator, verify: Verification.Fails, targetFramework: TargetFramework.Mscorlib40);
var verifier = CompileAndVerify(source, sourceSymbolValidator: sourceValidator, symbolValidator: metadataValidator, verify: Verification.TypeLoadFailed, targetFramework: TargetFramework.Mscorlib40);
}

#endregion
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2395,7 +2395,7 @@ static void Main()
CompileAndVerify(ca);

var cb = CreateCompilation(sourceB, options: TestOptions.ReleaseExe, assemblyName: "X", references: new[] { new CSharpCompilationReference(ca) });
CompileAndVerify(cb, expectedOutput: "42").Diagnostics.Verify();
CompileAndVerify(cb, expectedOutput: "42", verify: Verification.IVT).Diagnostics.Verify();
}

[Fact, WorkItem(1095618, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1095618")]
Expand Down
6 changes: 3 additions & 3 deletions src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncEHTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ public CodeGenAsyncEHTests()
{
}

private CompilationVerifier CompileAndVerify(string source, string expectedOutput = null, IEnumerable<MetadataReference> references = null, CSharpCompilationOptions options = null)
private CompilationVerifier CompileAndVerify(string source, string expectedOutput = null, IEnumerable<MetadataReference> references = null, CSharpCompilationOptions options = null, Verification verify = Verification.Passes)
{
references = (references != null) ? references.Concat(s_asyncRefs) : s_asyncRefs;
return base.CompileAndVerifyWithMscorlib40(source, expectedOutput: expectedOutput, references: references, options: options);
return base.CompileAndVerify(source, expectedOutput: expectedOutput, references: references, options: options, verify: verify);
}

[Fact]
Expand Down Expand Up @@ -1841,7 +1841,7 @@ public static void Main()
hello
2
";
CompileAndVerify(source, expectedOutput: expected);
CompileAndVerify(source, expectedOutput: expected, verify: Verification.LeaveIntoTry);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ public CodeGenAsyncSpillTests()
{
}

private CompilationVerifier CompileAndVerify(string source, string expectedOutput = null, IEnumerable<MetadataReference> references = null, CSharpCompilationOptions options = null)
private CompilationVerifier CompileAndVerify(string source, string expectedOutput = null, IEnumerable<MetadataReference> references = null, CSharpCompilationOptions options = null, Verification verify = Verification.Passes)
{
return base.CompileAndVerify(source, expectedOutput: expectedOutput, references: references, options: options);
return base.CompileAndVerify(source, expectedOutput: expectedOutput, references: references, options: options, verify: verify);
}

[Fact]
Expand Down Expand Up @@ -2478,7 +2478,7 @@ public static void Main()
2
0
";
CompileAndVerify(source, expectedOutput: expected);
CompileAndVerify(source, expectedOutput: expected, verify: Verification.RuntimeArgumentHandle);
}

[Fact]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ public void Deconstruct(out int a, out string b)
var right = tree.GetRoot().DescendantNodes().OfType<ObjectCreationExpressionSyntax>().Single();
Assert.Equal(@"new C()", right.ToString());
Assert.Equal("C", model.GetTypeInfo(right).Type.ToTestDisplayString());
Assert.Equal("C", model.GetTypeInfo(right).ConvertedType.ToTestDisplayString());
Assert.Equal(ConversionKind.Identity, model.GetConversion(right).Kind);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9558,7 +9558,7 @@ .locals init (int V_0, //a
IL_0066: callvirt ""void <>A{00000002}<System.Runtime.CompilerServices.CallSite, int, object>.Invoke(System.Runtime.CompilerServices.CallSite, ref int, object)""
IL_006b: ret
}
");
", verify: Verification.PassesPeVerify | Verification.FailsIlVerify); // ILVerify doesn't support TypedReference
}

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

var c = CompileAndVerifyUtil(text,
options: TestOptions.UnsafeReleaseDll,
verify: Verification.Fails);
verify: Verification.FailsPeVerify | Verification.PassesIlVerify); // PROTOTYPE(verification)

c.VerifyDiagnostics();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,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 @@ -1028,7 +1029,7 @@ public static void Main()
}
}
";
base.CompileAndVerify(source, expectedOutput: "12").
base.CompileAndVerify(source, verify: Verification.TypedReference, expectedOutput: "12").
VerifyIL("Test.Main",
@"
{
Expand Down
2 changes: 1 addition & 1 deletion src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenIterators.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2383,7 +2383,7 @@ 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);
var verifier = CompileAndVerify(compilation, verify: Verification.TypeLoadFailed);
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
7 changes: 5 additions & 2 deletions src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenMscorlib.cs
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,9 @@ 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
CompileAndVerify(comp, verify: Verification.Fails).

// PROTOTYPE(verification) Internal.TypeSystem.TypeSystemException + TypeLoadException : [TEMPORARY EXCEPTION MESSAGE] ClassLoadGeneral: System.String, 699fa24e-4ae5-4965-b7a7-166da051a9a9, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
CompileAndVerify(comp, verify: Verification.FailsPeVerify).
VerifyIL("program.Main()",
@"
{
Expand Down Expand Up @@ -867,7 +869,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)

CompileAndVerify(comp, verify: Verification.Fails).
// PROTOTYPE(verification) Internal.TypeSystem.TypeSystemException+TypeLoadException : [TEMPORARY EXCEPTION MESSAGE] ClassLoadGeneral: System.String, cb9df1f8-9e67-4084-a523-059b000cf4b6, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null
CompileAndVerify(comp, verify: Verification.FailsPeVerify).
VerifyIL("System.IntPtr..ctor(int)", @"
{
// Code size 10 (0xa)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2449,7 +2449,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 | Verification.PassesIlVerify).VerifyIL("Test.Main", @"
{
// Code size 65 (0x41)
.maxstack 4
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -552,7 +552,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.BadName);
var methodData = verifier.TestData.GetMethodData("<Initialize>");
Assert.Equal("System.Threading.Tasks.Task<object>", methodData.Method.ReturnType.ToDisplayString());
methodData.VerifyIL(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5202,7 +5202,8 @@ public RefLike M()
public ref struct RefLike{}
}
";
var verifier = CompileAndVerify(source, options: TestOptions.DebugExe.WithAllowUnsafe(true), expectedOutput: @"---
// PROTOTYPE(verification) Return type is ByRef, TypedReference, ArgHandle, or ArgIterator.
var verifier = CompileAndVerify(source, verify: Verification.PassesPeVerify | Verification.FailsIlVerify, options: TestOptions.DebugExe.WithAllowUnsafe(true), expectedOutput: @"---
M
---
---");
Expand Down
Loading