// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.IO;
using System.Linq;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
using System.Reflection.PortableExecutable;
using System.Text;
using Microsoft.CodeAnalysis.CodeGen;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Test.Utilities;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Test.PdbUtilities;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.CSharp.UnitTests.PDB
{
public class PDBTests : CSharpPDBTestBase
{
private static readonly MetadataReference[] s_valueTupleRefs = new[] { SystemRuntimeFacadeRef, ValueTupleRef };
#region General
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void EmitDebugInfoForSourceTextWithoutEncoding1()
{
var tree1 = SyntaxFactory.ParseSyntaxTree("class A { }", encoding: null, path: "Foo.cs");
var tree2 = SyntaxFactory.ParseSyntaxTree("class B { }", encoding: null, path: "");
var tree3 = SyntaxFactory.ParseSyntaxTree(SourceText.From("class C { }", encoding: null), path: "Bar.cs");
var tree4 = SyntaxFactory.ParseSyntaxTree("class D { }", encoding: Encoding.UTF8, path: "Baz.cs");
var comp = CSharpCompilation.Create("Compilation", new[] { tree1, tree2, tree3, tree4 }, new[] { MscorlibRef }, options: TestOptions.ReleaseDll);
var result = comp.Emit(new MemoryStream(), pdbStream: new MemoryStream());
result.Diagnostics.Verify(
// Foo.cs(1,1): error CS8055: Cannot emit debug information for a source text without encoding.
Diagnostic(ErrorCode.ERR_EncodinglessSyntaxTree, "class A { }").WithLocation(1, 1),
// Bar.cs(1,1): error CS8055: Cannot emit debug information for a source text without encoding.
Diagnostic(ErrorCode.ERR_EncodinglessSyntaxTree, "class C { }").WithLocation(1, 1));
Assert.False(result.Success);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void EmitDebugInfoForSourceTextWithoutEncoding2()
{
var tree1 = SyntaxFactory.ParseSyntaxTree("class A { public void F() { } }", encoding: Encoding.Unicode, path: "Foo.cs");
var tree2 = SyntaxFactory.ParseSyntaxTree("class B { public void F() { } }", encoding: null, path: "");
var tree3 = SyntaxFactory.ParseSyntaxTree("class C { public void F() { } }", encoding: new UTF8Encoding(true, false), path: "Bar.cs");
var tree4 = SyntaxFactory.ParseSyntaxTree(SourceText.From("class D { public void F() { } }", new UTF8Encoding(false, false)), path: "Baz.cs");
var comp = CSharpCompilation.Create("Compilation", new[] { tree1, tree2, tree3, tree4 }, new[] { MscorlibRef }, options: TestOptions.ReleaseDll);
var result = comp.Emit(new MemoryStream(), pdbStream: new MemoryStream());
result.Diagnostics.Verify();
Assert.True(result.Success);
var hash1 = CryptographicHashProvider.ComputeSha1(Encoding.Unicode.GetBytesWithPreamble(tree1.ToString())).ToArray();
var hash3 = CryptographicHashProvider.ComputeSha1(new UTF8Encoding(true, false).GetBytesWithPreamble(tree3.ToString())).ToArray();
var hash4 = CryptographicHashProvider.ComputeSha1(new UTF8Encoding(false, false).GetBytesWithPreamble(tree4.ToString())).ToArray();
comp.VerifyPdb(@"
", options: PdbValidationOptions.ExcludeMethods);
}
[WorkItem(846584, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/846584")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void RelativePathForExternalSource_Sha1()
{
var text1 = @"
#pragma checksum ""..\Test2.cs"" ""{406ea660-64cf-4c82-b6f0-42d48172a799}"" ""BA8CBEA9C2EFABD90D53B616FB80A081""
public class C
{
public void InitializeComponent() {
#line 4 ""..\Test2.cs""
InitializeComponent();
#line default
}
}
";
var compilation = CreateCompilation(
new[] { Parse(text1, @"C:\Folder1\Folder2\Test1.cs") },
options: TestOptions.DebugDll.WithSourceReferenceResolver(SourceFileResolver.Default));
compilation.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SymWriterErrors()
{
var source0 =
@"class C
{
}";
var compilation = CreateCompilation(source0, options: TestOptions.DebugDll);
// Verify full metadata contains expected rows.
var result = compilation.Emit(
peStream: new MemoryStream(),
metadataPEStream: null,
pdbStream: new MemoryStream(),
xmlDocumentationStream: null,
cancellationToken: default,
win32Resources: null,
manifestResources: null,
options: null,
debugEntryPoint: null,
sourceLinkStream: null,
embeddedTexts: null,
testData: new CompilationTestData() { SymWriterFactory = _ => new MockSymUnmanagedWriter() });
result.Diagnostics.Verify(
// error CS0041: Unexpected error writing debug information -- 'MockSymUnmanagedWriter error message'
Diagnostic(ErrorCode.FTL_DebugEmitFailure).WithArguments("MockSymUnmanagedWriter error message"));
Assert.False(result.Success);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SymWriterErrors2()
{
var source0 =
@"class C
{
}";
var compilation = CreateCompilation(source0, options: TestOptions.DebugDll);
// Verify full metadata contains expected rows.
var result = compilation.Emit(
peStream: new MemoryStream(),
metadataPEStream: null,
pdbStream: new MemoryStream(),
xmlDocumentationStream: null,
cancellationToken: default,
win32Resources: null,
manifestResources: null,
options: null,
debugEntryPoint: null,
sourceLinkStream: null,
embeddedTexts: null,
testData: new CompilationTestData() { SymWriterFactory = SymWriterTestUtilities.ThrowingFactory });
result.Diagnostics.Verify(
// error CS0041: Unexpected error writing debug information -- 'The version of Windows PDB writer is older than required: '''
Diagnostic(ErrorCode.FTL_DebugEmitFailure).WithArguments(string.Format(CodeAnalysisResources.SymWriterOlderVersionThanRequired, "")));
Assert.False(result.Success);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SymWriterErrors3()
{
var source0 =
@"class C
{
}";
var compilation = CreateCompilation(source0, options: TestOptions.DebugDll.WithDeterministic(true));
// Verify full metadata contains expected rows.
var result = compilation.Emit(
peStream: new MemoryStream(),
metadataPEStream: null,
pdbStream: new MemoryStream(),
xmlDocumentationStream: null,
cancellationToken: default,
win32Resources: null,
manifestResources: null,
options: null,
debugEntryPoint: null,
sourceLinkStream: null,
embeddedTexts: null,
testData: new CompilationTestData() { SymWriterFactory = SymWriterTestUtilities.ThrowingFactory });
result.Diagnostics.Verify(
// error CS0041: Unexpected error writing debug information -- 'Windows PDB writer doesn't support deterministic compilation: '''
Diagnostic(ErrorCode.FTL_DebugEmitFailure).WithArguments(string.Format(CodeAnalysisResources.SymWriterNotDeterministic, "")));
Assert.False(result.Success);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SymWriterErrors4()
{
var source0 =
@"class C
{
}";
var compilation = CreateCompilation(source0);
// Verify full metadata contains expected rows.
var result = compilation.Emit(
peStream: new MemoryStream(),
metadataPEStream: null,
pdbStream: new MemoryStream(),
xmlDocumentationStream: null,
cancellationToken: default,
win32Resources: null,
manifestResources: null,
options: null,
debugEntryPoint: null,
sourceLinkStream: null,
embeddedTexts: null,
testData: new CompilationTestData() { SymWriterFactory = _ => throw new DllNotFoundException("xxx") });
result.Diagnostics.Verify(
// error CS0041: Unexpected error writing debug information -- 'xxx'
Diagnostic(ErrorCode.FTL_DebugEmitFailure).WithArguments("xxx"));
Assert.False(result.Success);
}
[WorkItem(1067635, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1067635")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SuppressDynamicAndEncCDIForWinRT()
{
var source = @"
public class C
{
public static void F()
{
dynamic a = 1;
int b = 2;
foreach (var x in new[] { 1,2,3 })
{
System.Console.WriteLine(a * b);
}
}
}
";
var debug = CreateCompilation(source, new[] { CSharpRef }, options: TestOptions.DebugWinMD);
debug.VerifyPdb(@"
", format: DebugInformationFormat.Pdb, options: PdbValidationOptions.SkipConversionValidation);
var release = CreateCompilation(source, new[] { CSharpRef }, options: TestOptions.ReleaseWinMD);
release.VerifyPdb(@"
", format: DebugInformationFormat.Pdb, options: PdbValidationOptions.SkipConversionValidation);
}
[WorkItem(1067635, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/1067635")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SuppressTupleElementNamesCDIForWinRT()
{
var source =
@"class C
{
static void F()
{
(int A, int B) o = (1, 2);
}
}";
var debug = CreateCompilation(source, options: TestOptions.DebugWinMD);
debug.VerifyPdb(
@"
", format: DebugInformationFormat.Pdb, options: PdbValidationOptions.SkipConversionValidation);
var release = CreateCompilation(source, options: TestOptions.ReleaseWinMD);
release.VerifyPdb(
@"
", format: DebugInformationFormat.Pdb, options: PdbValidationOptions.SkipConversionValidation);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void DuplicateDocuments()
{
var source1 = @"class C { static void F() { } }";
var source2 = @"class D { static void F() { } }";
var tree1 = Parse(source1, @"foo.cs");
var tree2 = Parse(source2, @"foo.cs");
var comp = CreateCompilation(new[] { tree1, tree2 });
// the first file wins (checksum CB 22 ...)
comp.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void CustomDebugEntryPoint_DLL()
{
var source = @"class C { static void F() { } }";
var c = CreateCompilation(source, options: TestOptions.DebugDll);
var f = c.GetMember("C.F");
c.VerifyPdb(@"
", debugEntryPoint: f, options: PdbValidationOptions.ExcludeScopes | PdbValidationOptions.ExcludeSequencePoints | PdbValidationOptions.ExcludeCustomDebugInformation);
var peReader = new PEReader(c.EmitToArray(debugEntryPoint: f));
int peEntryPointToken = peReader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress;
Assert.Equal(0, peEntryPointToken);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void CustomDebugEntryPoint_EXE()
{
var source = @"class M { static void Main() { } } class C { static void F() { } }";
var c = CreateCompilation(source, options: TestOptions.DebugExe);
var f = c.GetMember("C.F");
c.VerifyPdb(@"
", debugEntryPoint: f, options: PdbValidationOptions.ExcludeScopes | PdbValidationOptions.ExcludeSequencePoints | PdbValidationOptions.ExcludeCustomDebugInformation);
var peReader = new PEReader(c.EmitToArray(debugEntryPoint: f));
int peEntryPointToken = peReader.PEHeaders.CorHeader.EntryPointTokenOrRelativeVirtualAddress;
var mdReader = peReader.GetMetadataReader();
var methodDef = mdReader.GetMethodDefinition((MethodDefinitionHandle)MetadataTokens.Handle(peEntryPointToken));
Assert.Equal("Main", mdReader.GetString(methodDef.Name));
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void CustomDebugEntryPoint_Errors()
{
var source1 = @"class C { static void F() { } } class D { static void G() {} }";
var source2 = @"class C { static void F() { } }";
var c1 = CreateCompilation(source1, options: TestOptions.DebugDll);
var c2 = CreateCompilation(source2, options: TestOptions.DebugDll);
var f1 = c1.GetMember("C.F");
var f2 = c2.GetMember("C.F");
var g = c1.GetMember("D.G");
var d = c1.GetMember("D");
Assert.NotNull(f1);
Assert.NotNull(f2);
Assert.NotNull(g);
Assert.NotNull(d);
var stInt = c1.GetSpecialType(SpecialType.System_Int32);
var d_t_g_int = g.Construct(stInt);
var d_int = d.Construct(stInt);
var d_int_g = d_int.GetMember("G");
var d_int_g_int = d_int_g.Construct(stInt);
var result = c1.Emit(new MemoryStream(), new MemoryStream(), debugEntryPoint: f2);
result.Diagnostics.Verify(
// error CS8096: Debug entry point must be a definition of a source method in the current compilation.
Diagnostic(ErrorCode.ERR_DebugEntryPointNotSourceMethodDefinition));
result = c1.Emit(new MemoryStream(), new MemoryStream(), debugEntryPoint: d_t_g_int);
result.Diagnostics.Verify(
// error CS8096: Debug entry point must be a definition of a source method in the current compilation.
Diagnostic(ErrorCode.ERR_DebugEntryPointNotSourceMethodDefinition));
result = c1.Emit(new MemoryStream(), new MemoryStream(), debugEntryPoint: d_int_g);
result.Diagnostics.Verify(
// error CS8096: Debug entry point must be a definition of a source method in the current compilation.
Diagnostic(ErrorCode.ERR_DebugEntryPointNotSourceMethodDefinition));
result = c1.Emit(new MemoryStream(), new MemoryStream(), debugEntryPoint: d_int_g_int);
result.Diagnostics.Verify(
// error CS8096: Debug entry point must be a definition of a source method in the current compilation.
Diagnostic(ErrorCode.ERR_DebugEntryPointNotSourceMethodDefinition));
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
[WorkItem(768862, "https://devdiv.visualstudio.com/DevDiv/_workitems/edit/768862")]
public void TestLargeLineDelta()
{
var verbatim = string.Join("\r\n", Enumerable.Repeat("x", 1000));
var source = $@"
class C {{ public static void Main() => System.Console.WriteLine(@""{verbatim}""); }}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C.Main", @"
", format: DebugInformationFormat.PortablePdb);
// Native PDBs only support spans with line delta <= 127 (7 bit)
// https://github.com/Microsoft/microsoft-pdb/blob/master/include/cvinfo.h#L4621
c.VerifyPdb("C.Main", @"
", format: DebugInformationFormat.Pdb);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
[WorkItem(20118, "https://github.com/dotnet/roslyn/issues/20118")]
public void TestLargeStartAndEndColumn_SameLine()
{
var spaces = new string(' ', 0x10000);
var source = $@"
class C
{{
public static void Main() =>
{spaces}System.Console.WriteLine(""{spaces}"");
}}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C.Main", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
[WorkItem(20118, "https://github.com/dotnet/roslyn/issues/20118")]
public void TestLargeStartAndEndColumn_DifferentLine()
{
var spaces = new string(' ', 0x10000);
var source = $@"
class C
{{
public static void Main() =>
{spaces}System.Console.WriteLine(
""{spaces}"");
}}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C.Main", @"
");
}
#endregion
#region Method Bodies
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void TestBasic()
{
var source = @"
class Program
{
Program() { }
static void Main(string[] args)
{
Program p = new Program();
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("Program.Main", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void TestSimpleLocals()
{
var source = @"
class C
{
void Method()
{ //local at method scope
object version = 6;
System.Console.WriteLine(""version {0}"", version);
{
//a scope that defines no locals
{
//a nested local
object foob = 1;
System.Console.WriteLine(""foob {0}"", foob);
}
{
//a nested local
int foob1 = 1;
System.Console.WriteLine(""foob1 {0}"", foob1);
}
System.Console.WriteLine(""Eva"");
}
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C.Method", @"
");
}
[WorkItem(7244, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/7244")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ConstructorsWithoutInitializers()
{
var source =
@"class C
{
C()
{
object o;
}
C(object x)
{
object y = x;
}
}";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C..ctor",
@"
");
}
[WorkItem(7244, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/7244")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ConstructorsWithInitializers()
{
var source =
@"class C
{
static object G = 1;
object F = G;
C()
{
object o;
}
C(object x)
{
object y = x;
}
}";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C..ctor",
@"
");
}
///
/// Although the debugging info attached to DebuggerHidden method is not used by the debugger
/// (the debugger doesn't ever stop in the method) Dev11 emits the info and so do we.
///
/// StepThrough method needs the information if JustMyCode is disabled and a breakpoint is set within the method.
/// NonUserCode method needs the information if JustMyCode is disabled.
///
/// It's up to the tool that consumes the debugging information, not the compiler to decide whether to ignore the info or not.
/// BTW, the information can actually be retrieved at runtime from the PDB file via Reflection StackTrace.
///
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void MethodsWithDebuggerAttributes()
{
var source = @"
using System;
using System.Diagnostics;
class Program
{
[DebuggerHidden]
static void Hidden()
{
int x = 1;
Console.WriteLine(x);
}
[DebuggerStepThrough]
static void StepThrough()
{
int y = 1;
Console.WriteLine(y);
}
[DebuggerNonUserCode]
static void NonUserCode()
{
int z = 1;
Console.WriteLine(z);
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb(@"
");
}
///
/// If a synthesized method contains any user code,
/// the method must have a sequence point at
/// offset 0 for correct stepping behavior.
///
[WorkItem(804681, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/804681")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SequencePointAtOffset0()
{
string source =
@"using System;
class C
{
static Func F = x =>
{
Func f = o => 1;
Func, Func> g = h => y => h(y);
return g(f)(null);
};
}";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb(@"
2
");
}
///
/// Leading trivia is not included in the syntax offset.
///
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffsetInPresenceOfTrivia_Methods()
{
string source = @"
class C
{
public static void Main1() /*Comment1*/{/*Comment2*/int a = 1;/*Comment3*/}/*Comment4*/
public static void Main2() {/*Comment2*/int a = 2;/*Comment3*/}/*Comment4*/
}";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
// verify that both syntax offsets are the same
c.VerifyPdb(@"
");
}
///
/// Leading and trailing trivia are not included in the syntax offset.
///
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffsetInPresenceOfTrivia_Initializers()
{
string source = @"
using System;
class C1
{
public static Func e=() => 0;
public static Func f/*Comment0*/=/*Comment1*/() => 1;/*Comment2*/
public static Func g=() => 2;
}
class C2
{
public static Func e=() => 0;
public static Func f=/*Comment1*/() => 1;
public static Func g=() => 2;
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
// verify that syntax offsets of both .cctor's are the same
c.VerifyPdb("C1..cctor", @"
4
");
c.VerifyPdb("C2..cctor", @"
4
");
}
#endregion
#region ReturnStatement
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void Return_Method1()
{
var source = @"
class Program
{
static int Main()
{
return 1;
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
// In order to place a breakpoint on the closing brace we need to save the return expression value to
// a local and then load it again (since sequence point needs an empty stack). This variable has to be marked as long-lived.
v.VerifyIL("Program.Main", @"
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0)
-IL_0000: nop
-IL_0001: ldc.i4.1
IL_0002: stloc.0
IL_0003: br.s IL_0005
-IL_0005: ldloc.0
IL_0006: ret
}", sequencePoints: "Program.Main");
v.VerifyPdb("Program.Main", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void Return_Property1()
{
var source = @"
class C
{
static int P
{
get { return 1; }
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
// In order to place a breakpoint on the closing brace we need to save the return expression value to
// a local and then load it again (since sequence point needs an empty stack). This variable has to be marked as long-lived.
v.VerifyIL("C.P.get", @"
{
// Code size 7 (0x7)
.maxstack 1
.locals init (int V_0)
-IL_0000: nop
-IL_0001: ldc.i4.1
IL_0002: stloc.0
IL_0003: br.s IL_0005
-IL_0005: ldloc.0
IL_0006: ret
}", sequencePoints: "C.get_P");
v.VerifyPdb("C.get_P", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void Return_Void1()
{
var source = @"
class Program
{
static void Main()
{
return;
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
v.VerifyIL("Program.Main", @"
{
// Code size 4 (0x4)
.maxstack 0
-IL_0000: nop
-IL_0001: br.s IL_0003
-IL_0003: ret
}", sequencePoints: "Program.Main");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void Return_ExpressionBodied1()
{
var source = @"
class Program
{
static int Main() => 1;
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
v.VerifyIL("Program.Main", @"
{
// Code size 2 (0x2)
.maxstack 1
-IL_0000: ldc.i4.1
IL_0001: ret
}", sequencePoints: "Program.Main");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void Return_FromExceptionHandler1()
{
var source = @"
using System;
class Program
{
static int Main()
{
try
{
Console.WriteLine();
return 1;
}
catch (Exception)
{
return 2;
}
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
v.VerifyIL("Program.Main", @"
{
// Code size 20 (0x14)
.maxstack 1
.locals init (int V_0)
-IL_0000: nop
.try
{
-IL_0001: nop
-IL_0002: call ""void System.Console.WriteLine()""
IL_0007: nop
-IL_0008: ldc.i4.1
IL_0009: stloc.0
IL_000a: leave.s IL_0012
}
catch System.Exception
{
-IL_000c: pop
-IL_000d: nop
-IL_000e: ldc.i4.2
IL_000f: stloc.0
IL_0010: leave.s IL_0012
}
-IL_0012: ldloc.0
IL_0013: ret
}", sequencePoints: "Program.Main");
v.VerifyPdb("Program.Main", @"
");
}
#endregion
#region IfStatement
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void IfStatement()
{
var source = @"
class C
{
void Method()
{
bool b = true;
if (b)
{
string s = ""true"";
System.Console.WriteLine(s);
}
else
{
string s = ""false"";
int i = 1;
while (i < 100)
{
int j = i, k = 1;
System.Console.WriteLine(j);
i = j + k;
}
i = i + 1;
}
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C.Method", @"
");
}
#endregion
#region WhileStatement
[WorkItem(538299, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538299")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void WhileStatement()
{
var source = @"using System;
public class SeqPointForWhile
{
public static void Main()
{
SeqPointForWhile obj = new SeqPointForWhile();
obj.While(234);
}
int field;
public void While(int p)
{
while (p > 0) // SeqPt should be generated at the end of loop
{
p = (int)(p / 2);
if (p > 100)
{
continue;
}
else if (p > 10)
{
int x = p;
field = x;
}
else
{
int x = p;
Console.WriteLine(x);
break;
}
}
field = -1;
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.ReleaseExe);
// Offset 0x01 should be:
//
// Move original offset 0x01 to 0x33
//
//
// Note: 16707566 == 0x00FEEFEE
c.VerifyPdb(@"
");
}
#endregion
#region ForStatement
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ForStatement1()
{
var source = @"
class C
{
static bool F(int i) { return true; }
static void G(int i) { }
static void M()
{
for (int i = 1; F(i); G(i))
{
System.Console.WriteLine(1);
}
}
}";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C.M", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ForStatement2()
{
var source = @"
class C
{
static void M()
{
for (;;)
{
System.Console.WriteLine(1);
}
}
}";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C.M", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ForStatement3()
{
var source = @"
class C
{
static void M()
{
int i = 0;
for (;;i++)
{
System.Console.WriteLine(i);
}
}
}";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C.M", @"
");
}
#endregion
#region ForEachStatement
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ForEachStatement_String()
{
var source = @"
public class C
{
public static void Main()
{
foreach (var c in ""hello"")
{
System.Console.WriteLine(c);
}
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.ReleaseExe);
// Sequence points:
// 1) Open brace at start of method
// 2) 'foreach'
// 3) '"hello"'
// 4) Hidden initial jump (of for loop)
// 5) 'var c'
// 6) Open brace of loop
// 7) Loop body
// 8) Close brace of loop
// 9) Hidden index increment.
// 10) 'in'
// 11) Close brace at end of method
c.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ForEachStatement_Array()
{
var source = @"
public class C
{
public static void Main()
{
foreach (var x in new int[2])
{
System.Console.WriteLine(x);
}
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
// Sequence points:
// 1) Open brace at start of method
// 2) 'foreach'
// 3) 'new int[2]'
// 4) Hidden initial jump (of for loop)
// 5) 'var c'
// 6) Open brace of loop
// 7) Loop body
// 8) Close brace of loop
// 9) Hidden index increment.
// 10) 'in'
// 11) Close brace at end of method
c.VerifyPdb(@"
");
}
[WorkItem(544937, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544937")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ForEachStatement_MultiDimensionalArray()
{
var source = @"
public class C
{
public static void Main()
{
foreach (var x in new int[2, 3])
{
System.Console.WriteLine(x);
}
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
// Sequence points:
// 1) Open brace at start of method
// 2) 'foreach'
// 3) 'new int[2, 3]'
// 4) Hidden initial jump (of for loop)
// 5) 'var c'
// 6) Open brace of loop
// 7) Loop body
// 8) Close brace of loop
// 9) 'in'
// 10) Close brace at end of method
v.VerifyIL("C.Main", @"
{
// Code size 88 (0x58)
.maxstack 3
.locals init (int[,] V_0,
int V_1,
int V_2,
int V_3,
int V_4,
int V_5) //x
-IL_0000: nop
-IL_0001: nop
-IL_0002: ldc.i4.2
IL_0003: ldc.i4.3
IL_0004: newobj ""int[*,*]..ctor""
IL_0009: stloc.0
IL_000a: ldloc.0
IL_000b: ldc.i4.0
IL_000c: callvirt ""int System.Array.GetUpperBound(int)""
IL_0011: stloc.1
IL_0012: ldloc.0
IL_0013: ldc.i4.1
IL_0014: callvirt ""int System.Array.GetUpperBound(int)""
IL_0019: stloc.2
IL_001a: ldloc.0
IL_001b: ldc.i4.0
IL_001c: callvirt ""int System.Array.GetLowerBound(int)""
IL_0021: stloc.3
~IL_0022: br.s IL_0053
IL_0024: ldloc.0
IL_0025: ldc.i4.1
IL_0026: callvirt ""int System.Array.GetLowerBound(int)""
IL_002b: stloc.s V_4
~IL_002d: br.s IL_004a
-IL_002f: ldloc.0
IL_0030: ldloc.3
IL_0031: ldloc.s V_4
IL_0033: call ""int[*,*].Get""
IL_0038: stloc.s V_5
-IL_003a: nop
-IL_003b: ldloc.s V_5
IL_003d: call ""void System.Console.WriteLine(int)""
IL_0042: nop
-IL_0043: nop
~IL_0044: ldloc.s V_4
IL_0046: ldc.i4.1
IL_0047: add
IL_0048: stloc.s V_4
-IL_004a: ldloc.s V_4
IL_004c: ldloc.2
IL_004d: ble.s IL_002f
~IL_004f: ldloc.3
IL_0050: ldc.i4.1
IL_0051: add
IL_0052: stloc.3
-IL_0053: ldloc.3
IL_0054: ldloc.1
IL_0055: ble.s IL_0024
-IL_0057: ret
}
", sequencePoints: "C.Main");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
[WorkItem(12564, "https://github.com/dotnet/roslyn/issues/12564")]
public void ConditionalInAsyncMethod()
{
var source = @"
using System;
class Program
{
public static async void Test()
{
int i = 0;
if (i != 0)
Console
.WriteLine();
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
v.VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"
{
// Code size 81 (0x51)
.maxstack 2
.locals init (int V_0,
bool V_1,
System.Exception V_2)
// sequence point:
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.d__0.<>1__state""
IL_0006: stloc.0
.try
{
// sequence point: {
IL_0007: nop
// sequence point: int i = 0;
IL_0008: ldarg.0
IL_0009: ldc.i4.0
IL_000a: stfld ""int Program.d__0.5__1""
// sequence point: if (i != 0)
IL_000f: ldarg.0
IL_0010: ldfld ""int Program.d__0.5__1""
IL_0015: ldc.i4.0
IL_0016: cgt.un
IL_0018: stloc.1
// sequence point:
IL_0019: ldloc.1
IL_001a: brfalse.s IL_0022
// sequence point: Console ... .WriteLine()
IL_001c: call ""void System.Console.WriteLine()""
IL_0021: nop
// sequence point:
IL_0022: leave.s IL_003c
}
catch System.Exception
{
// async: catch handler, sequence point:
IL_0024: stloc.2
IL_0025: ldarg.0
IL_0026: ldc.i4.s -2
IL_0028: stfld ""int Program.d__0.<>1__state""
IL_002d: ldarg.0
IL_002e: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.d__0.<>t__builder""
IL_0033: ldloc.2
IL_0034: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetException(System.Exception)""
IL_0039: nop
IL_003a: leave.s IL_0050
}
// sequence point: }
IL_003c: ldarg.0
IL_003d: ldc.i4.s -2
IL_003f: stfld ""int Program.d__0.<>1__state""
// sequence point:
IL_0044: ldarg.0
IL_0045: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.d__0.<>t__builder""
IL_004a: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult()""
IL_004f: nop
IL_0050: ret
}
", sequencePoints: "Program+d__0.MoveNext", source: source);
v.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
[WorkItem(12564, "https://github.com/dotnet/roslyn/issues/12564")]
public void ConditionalBeforeLocalFunction()
{
var source = @"
class C
{
void M()
{
int i = 0;
if (i != 0)
{
return;
}
string local()
{
throw null;
}
System.Console.Write(1);
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
v.VerifyIL("C.M", @"
{
// Code size 23 (0x17)
.maxstack 2
.locals init (int V_0, //i
bool V_1)
// sequence point: {
IL_0000: nop
// sequence point: int i = 0;
IL_0001: ldc.i4.0
IL_0002: stloc.0
// sequence point: if (i != 0)
IL_0003: ldloc.0
IL_0004: ldc.i4.0
IL_0005: cgt.un
IL_0007: stloc.1
// sequence point:
IL_0008: ldloc.1
IL_0009: brfalse.s IL_000e
// sequence point: {
IL_000b: nop
// sequence point: return;
IL_000c: br.s IL_0016
// sequence point:
IL_000e: nop
// sequence point: System.Console.Write(1);
IL_000f: ldc.i4.1
IL_0010: call ""void System.Console.Write(int)""
IL_0015: nop
// sequence point: }
IL_0016: ret
}
", sequencePoints: "C.M", source: source);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
[WorkItem(12564, "https://github.com/dotnet/roslyn/issues/12564")]
public void ConditionalInAsyncMethodWithExplicitReturn()
{
var source = @"
using System;
class Program
{
public static async void Test()
{
int i = 0;
if (i != 0)
Console
.WriteLine();
return;
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
v.VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"
{
// Code size 81 (0x51)
.maxstack 2
.locals init (int V_0,
bool V_1,
System.Exception V_2)
// sequence point:
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.d__0.<>1__state""
IL_0006: stloc.0
.try
{
// sequence point: {
IL_0007: nop
// sequence point: int i = 0;
IL_0008: ldarg.0
IL_0009: ldc.i4.0
IL_000a: stfld ""int Program.d__0.5__1""
// sequence point: if (i != 0)
IL_000f: ldarg.0
IL_0010: ldfld ""int Program.d__0.5__1""
IL_0015: ldc.i4.0
IL_0016: cgt.un
IL_0018: stloc.1
// sequence point:
IL_0019: ldloc.1
IL_001a: brfalse.s IL_0022
// sequence point: Console ... .WriteLine()
IL_001c: call ""void System.Console.WriteLine()""
IL_0021: nop
// sequence point: return;
IL_0022: leave.s IL_003c
}
catch System.Exception
{
// async: catch handler, sequence point:
IL_0024: stloc.2
IL_0025: ldarg.0
IL_0026: ldc.i4.s -2
IL_0028: stfld ""int Program.d__0.<>1__state""
IL_002d: ldarg.0
IL_002e: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.d__0.<>t__builder""
IL_0033: ldloc.2
IL_0034: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetException(System.Exception)""
IL_0039: nop
IL_003a: leave.s IL_0050
}
// sequence point: }
IL_003c: ldarg.0
IL_003d: ldc.i4.s -2
IL_003f: stfld ""int Program.d__0.<>1__state""
// sequence point:
IL_0044: ldarg.0
IL_0045: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.d__0.<>t__builder""
IL_004a: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult()""
IL_004f: nop
IL_0050: ret
}
", sequencePoints: "Program+d__0.MoveNext", source: source);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
[WorkItem(12564, "https://github.com/dotnet/roslyn/issues/12564")]
public void ConditionalInSimpleMethod()
{
var source = @"
using System;
class Program
{
public static void Test()
{
int i = 0;
if (i != 0)
Console.WriteLine();
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
v.VerifyIL("Program.Test()", @"
{
// Code size 18 (0x12)
.maxstack 2
.locals init (int V_0, //i
bool V_1)
// sequence point: {
IL_0000: nop
// sequence point: int i = 0;
IL_0001: ldc.i4.0
IL_0002: stloc.0
// sequence point: if (i != 0)
IL_0003: ldloc.0
IL_0004: ldc.i4.0
IL_0005: cgt.un
IL_0007: stloc.1
// sequence point:
IL_0008: ldloc.1
IL_0009: brfalse.s IL_0011
// sequence point: Console.WriteLine();
IL_000b: call ""void System.Console.WriteLine()""
IL_0010: nop
// sequence point: }
IL_0011: ret
}
", sequencePoints: "Program.Test", source: source);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
[WorkItem(12564, "https://github.com/dotnet/roslyn/issues/12564")]
public void ElseConditionalInAsyncMethod()
{
var source = @"
using System;
class Program
{
public static async void Test()
{
int i = 0;
if (i != 0)
Console.WriteLine(""one"");
else
Console.WriteLine(""other"");
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
v.VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"
{
// Code size 99 (0x63)
.maxstack 2
.locals init (int V_0,
bool V_1,
System.Exception V_2)
// sequence point:
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.d__0.<>1__state""
IL_0006: stloc.0
.try
{
// sequence point: {
IL_0007: nop
// sequence point: int i = 0;
IL_0008: ldarg.0
IL_0009: ldc.i4.0
IL_000a: stfld ""int Program.d__0.5__1""
// sequence point: if (i != 0)
IL_000f: ldarg.0
IL_0010: ldfld ""int Program.d__0.5__1""
IL_0015: ldc.i4.0
IL_0016: cgt.un
IL_0018: stloc.1
// sequence point:
IL_0019: ldloc.1
IL_001a: brfalse.s IL_0029
// sequence point: Console.WriteLine(""one"");
IL_001c: ldstr ""one""
IL_0021: call ""void System.Console.WriteLine(string)""
IL_0026: nop
IL_0027: br.s IL_0034
// sequence point: Console.WriteLine(""other"");
IL_0029: ldstr ""other""
IL_002e: call ""void System.Console.WriteLine(string)""
IL_0033: nop
// sequence point:
IL_0034: leave.s IL_004e
}
catch System.Exception
{
// async: catch handler, sequence point:
IL_0036: stloc.2
IL_0037: ldarg.0
IL_0038: ldc.i4.s -2
IL_003a: stfld ""int Program.d__0.<>1__state""
IL_003f: ldarg.0
IL_0040: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.d__0.<>t__builder""
IL_0045: ldloc.2
IL_0046: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetException(System.Exception)""
IL_004b: nop
IL_004c: leave.s IL_0062
}
// sequence point: }
IL_004e: ldarg.0
IL_004f: ldc.i4.s -2
IL_0051: stfld ""int Program.d__0.<>1__state""
// sequence point:
IL_0056: ldarg.0
IL_0057: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.d__0.<>t__builder""
IL_005c: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult()""
IL_0061: nop
IL_0062: ret
}
", sequencePoints: "Program+d__0.MoveNext", source: source);
v.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
[WorkItem(12564, "https://github.com/dotnet/roslyn/issues/12564")]
public void ConditionalInTry()
{
var source = @"
using System;
class Program
{
public static void Test()
{
try
{
int i = 0;
if (i != 0)
Console.WriteLine();
}
catch { }
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
v.VerifyIL("Program.Test", @"
{
// Code size 27 (0x1b)
.maxstack 2
.locals init (int V_0, //i
bool V_1)
// sequence point: {
IL_0000: nop
.try
{
// sequence point: {
IL_0001: nop
// sequence point: int i = 0;
IL_0002: ldc.i4.0
IL_0003: stloc.0
// sequence point: if (i != 0)
IL_0004: ldloc.0
IL_0005: ldc.i4.0
IL_0006: cgt.un
IL_0008: stloc.1
// sequence point:
IL_0009: ldloc.1
IL_000a: brfalse.s IL_0012
// sequence point: Console.WriteLine();
IL_000c: call ""void System.Console.WriteLine()""
IL_0011: nop
// sequence point: }
IL_0012: nop
IL_0013: leave.s IL_001a
}
catch object
{
// sequence point: catch
IL_0015: pop
// sequence point: {
IL_0016: nop
// sequence point: }
IL_0017: nop
IL_0018: leave.s IL_001a
}
// sequence point: }
IL_001a: ret
}
", sequencePoints: "Program.Test", source: source);
v.VerifyPdb(@"
");
}
[WorkItem(544937, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544937")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ForEachStatement_MultiDimensionalArrayBreakAndContinue()
{
var source = @"
using System;
class C
{
static void Main()
{
int[, ,] array = new[,,]
{
{ {1, 2}, {3, 4} },
{ {5, 6}, {7, 8} },
};
foreach (int i in array)
{
if (i % 2 == 1) continue;
if (i > 4) break;
Console.WriteLine(i);
}
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll.WithModuleName("MODULE"));
// Stepping:
// After "continue", step to "in".
// After "break", step to first sequence point following loop body (in this case, method close brace).
v.VerifyIL("C.Main", @"
{
// Code size 169 (0xa9)
.maxstack 4
.locals init (int[,,] V_0, //array
int[,,] V_1,
int V_2,
int V_3,
int V_4,
int V_5,
int V_6,
int V_7,
int V_8, //i
bool V_9,
bool V_10)
-IL_0000: nop
-IL_0001: ldc.i4.2
IL_0002: ldc.i4.2
IL_0003: ldc.i4.2
IL_0004: newobj ""int[*,*,*]..ctor""
IL_0009: dup
IL_000a: ldtoken "".__StaticArrayInitTypeSize=32 .EB196F988F4F427D318CA25B68671CF3A4510012""
IL_000f: call ""void System.Runtime.CompilerServices.RuntimeHelpers.InitializeArray(System.Array, System.RuntimeFieldHandle)""
IL_0014: stloc.0
-IL_0015: nop
-IL_0016: ldloc.0
IL_0017: stloc.1
IL_0018: ldloc.1
IL_0019: ldc.i4.0
IL_001a: callvirt ""int System.Array.GetUpperBound(int)""
IL_001f: stloc.2
IL_0020: ldloc.1
IL_0021: ldc.i4.1
IL_0022: callvirt ""int System.Array.GetUpperBound(int)""
IL_0027: stloc.3
IL_0028: ldloc.1
IL_0029: ldc.i4.2
IL_002a: callvirt ""int System.Array.GetUpperBound(int)""
IL_002f: stloc.s V_4
IL_0031: ldloc.1
IL_0032: ldc.i4.0
IL_0033: callvirt ""int System.Array.GetLowerBound(int)""
IL_0038: stloc.s V_5
~IL_003a: br.s IL_00a3
IL_003c: ldloc.1
IL_003d: ldc.i4.1
IL_003e: callvirt ""int System.Array.GetLowerBound(int)""
IL_0043: stloc.s V_6
~IL_0045: br.s IL_0098
IL_0047: ldloc.1
IL_0048: ldc.i4.2
IL_0049: callvirt ""int System.Array.GetLowerBound(int)""
IL_004e: stloc.s V_7
~IL_0050: br.s IL_008c
-IL_0052: ldloc.1
IL_0053: ldloc.s V_5
IL_0055: ldloc.s V_6
IL_0057: ldloc.s V_7
IL_0059: call ""int[*,*,*].Get""
IL_005e: stloc.s V_8
-IL_0060: nop
-IL_0061: ldloc.s V_8
IL_0063: ldc.i4.2
IL_0064: rem
IL_0065: ldc.i4.1
IL_0066: ceq
IL_0068: stloc.s V_9
~IL_006a: ldloc.s V_9
IL_006c: brfalse.s IL_0070
-IL_006e: br.s IL_0086
-IL_0070: ldloc.s V_8
IL_0072: ldc.i4.4
IL_0073: cgt
IL_0075: stloc.s V_10
~IL_0077: ldloc.s V_10
IL_0079: brfalse.s IL_007d
-IL_007b: br.s IL_00a8
-IL_007d: ldloc.s V_8
IL_007f: call ""void System.Console.WriteLine(int)""
IL_0084: nop
-IL_0085: nop
~IL_0086: ldloc.s V_7
IL_0088: ldc.i4.1
IL_0089: add
IL_008a: stloc.s V_7
-IL_008c: ldloc.s V_7
IL_008e: ldloc.s V_4
IL_0090: ble.s IL_0052
~IL_0092: ldloc.s V_6
IL_0094: ldc.i4.1
IL_0095: add
IL_0096: stloc.s V_6
-IL_0098: ldloc.s V_6
IL_009a: ldloc.3
IL_009b: ble.s IL_0047
~IL_009d: ldloc.s V_5
IL_009f: ldc.i4.1
IL_00a0: add
IL_00a1: stloc.s V_5
-IL_00a3: ldloc.s V_5
IL_00a5: ldloc.2
IL_00a6: ble.s IL_003c
-IL_00a8: ret
}
", sequencePoints: "C.Main");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ForEachStatement_Enumerator()
{
var source = @"
public class C
{
public static void Main()
{
foreach (var x in new System.Collections.Generic.List())
{
System.Console.WriteLine(x);
}
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
// Sequence points:
// 1) Open brace at start of method
// 2) 'foreach'
// 3) 'new System.Collections.Generic.List()'
// 4) Hidden initial jump (of while loop)
// 5) 'var c'
// 6) Open brace of loop
// 7) Loop body
// 8) Close brace of loop
// 9) 'in'
// 10) hidden point in Finally
// 11) Close brace at end of method
v.VerifyIL("C.Main", @"
{
// Code size 59 (0x3b)
.maxstack 1
.locals init (System.Collections.Generic.List.Enumerator V_0,
int V_1) //x
-IL_0000: nop
-IL_0001: nop
-IL_0002: newobj ""System.Collections.Generic.List..ctor()""
IL_0007: call ""System.Collections.Generic.List.Enumerator System.Collections.Generic.List.GetEnumerator()""
IL_000c: stloc.0
.try
{
~IL_000d: br.s IL_0020
-IL_000f: ldloca.s V_0
IL_0011: call ""int System.Collections.Generic.List.Enumerator.Current.get""
IL_0016: stloc.1
-IL_0017: nop
-IL_0018: ldloc.1
IL_0019: call ""void System.Console.WriteLine(int)""
IL_001e: nop
-IL_001f: nop
-IL_0020: ldloca.s V_0
IL_0022: call ""bool System.Collections.Generic.List.Enumerator.MoveNext()""
IL_0027: brtrue.s IL_000f
IL_0029: leave.s IL_003a
}
finally
{
~IL_002b: ldloca.s V_0
IL_002d: constrained. ""System.Collections.Generic.List.Enumerator""
IL_0033: callvirt ""void System.IDisposable.Dispose()""
IL_0038: nop
IL_0039: endfinally
}
-IL_003a: ret
}
", sequencePoints: "C.Main");
}
[WorkItem(718501, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/718501")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ForEachNops()
{
string source = @"
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
private static List> l = new List>();
static void Main(string[] args)
{
foreach (var i in l.AsEnumerable())
{
switch (i.Count)
{
case 1:
break;
default:
if (i.Count != 0)
{
}
break;
}
}
}
}
";
// we just want this to compile without crashing/asserting
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("Program.Main", @"
"
);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ForEachStatement_Deconstruction()
{
var source = @"
public class C
{
public static (int, (bool, double))[] F() => new[] { (1, (true, 2.0)) };
public static void Main()
{
foreach (var (c, (d, e)) in F())
{
System.Console.WriteLine(c);
}
}
}
";
var c = CreateCompilation(source, options: TestOptions.DebugDll);
var v = CompileAndVerify(c);
v.VerifyIL("C.Main", @"
{
// Code size 70 (0x46)
.maxstack 2
.locals init ((int, (bool, double))[] V_0,
int V_1,
int V_2, //c
bool V_3, //d
double V_4, //e
System.ValueTuple V_5)
// sequence point: {
IL_0000: nop
// sequence point: foreach
IL_0001: nop
// sequence point: F()
IL_0002: call ""(int, (bool, double))[] C.F()""
IL_0007: stloc.0
IL_0008: ldc.i4.0
IL_0009: stloc.1
// sequence point:
IL_000a: br.s IL_003f
// sequence point: var (c, (d, e))
IL_000c: ldloc.0
IL_000d: ldloc.1
IL_000e: ldelem ""System.ValueTuple""
IL_0013: dup
IL_0014: ldfld ""(bool, double) System.ValueTuple.Item2""
IL_0019: stloc.s V_5
IL_001b: ldfld ""int System.ValueTuple.Item1""
IL_0020: stloc.2
IL_0021: ldloc.s V_5
IL_0023: ldfld ""bool System.ValueTuple.Item1""
IL_0028: stloc.3
IL_0029: ldloc.s V_5
IL_002b: ldfld ""double System.ValueTuple.Item2""
IL_0030: stloc.s V_4
// sequence point: {
IL_0032: nop
// sequence point: System.Console.WriteLine(c);
IL_0033: ldloc.2
IL_0034: call ""void System.Console.WriteLine(int)""
IL_0039: nop
// sequence point: }
IL_003a: nop
// sequence point:
IL_003b: ldloc.1
IL_003c: ldc.i4.1
IL_003d: add
IL_003e: stloc.1
// sequence point: in
IL_003f: ldloc.1
IL_0040: ldloc.0
IL_0041: ldlen
IL_0042: conv.i4
IL_0043: blt.s IL_000c
// sequence point: }
IL_0045: ret
}
", sequencePoints: "C.Main", source: source);
v.VerifyPdb(@"
");
}
#endregion
#region Switch
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SwitchWithPattern_01()
{
string source = @"
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
private static List> l = new List>();
static void Main(string[] args)
{
Student s = new Student();
s.Name = ""Bozo"";
s.GPA = 2.3;
Operate(s);
}
static string Operate(Person p)
{
switch (p)
{
case Student s when s.GPA > 3.5:
return $""Student {s.Name} ({s.GPA:N1})"";
case Student s:
return $""Student {s.Name} ({s.GPA:N1})"";
case Teacher t:
return $""Teacher {t.Name} of {t.Subject}"";
default:
return $""Person {p.Name}"";
}
}
}
class Person { public string Name; }
class Teacher : Person { public string Subject; }
class Student : Person { public double GPA; }
";
// we just want this to compile without crashing/asserting
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("Program.Operate",
@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SwitchWithPattern_02()
{
string source = @"
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
private static List> l = new List>();
static void Main(string[] args)
{
Student s = new Student();
s.Name = ""Bozo"";
s.GPA = 2.3;
Operate(s);
}
static System.Func Operate(Person p)
{
switch (p)
{
case Student s when s.GPA > 3.5:
return () => $""Student {s.Name} ({s.GPA:N1})"";
case Student s:
return () => $""Student {s.Name} ({s.GPA:N1})"";
case Teacher t:
return () => $""Teacher {t.Name} of {t.Subject}"";
default:
return () => $""Person {p.Name}"";
}
}
}
class Person { public string Name; }
class Teacher : Person { public string Subject; }
class Student : Person { public double GPA; }
";
// we just want this to compile without crashing/asserting
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("Program.Operate",
@"
2
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SwitchWithPatternAndLocalFunctions()
{
string source = @"
using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
private static List> l = new List>();
static void Main(string[] args)
{
Student s = new Student();
s.Name = ""Bozo"";
s.GPA = 2.3;
Operate(s);
}
static System.Func Operate(Person p)
{
switch (p)
{
case Student s when s.GPA > 3.5:
string f1() => $""Student {s.Name} ({s.GPA:N1})"";
return f1;
case Student s:
string f2() => $""Student {s.Name} ({s.GPA:N1})"";
return f2;
case Teacher t:
string f3() => $""Teacher {t.Name} of {t.Subject}"";
return f3;
default:
string f4() => $""Person {p.Name}"";
return f4;
}
}
}
class Person { public string Name; }
class Teacher : Person { public string Subject; }
class Student : Person { public double GPA; }
";
// we just want this to compile without crashing/asserting
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("Program.Operate", @"
2
");
}
[WorkItem(17090, "https://github.com/dotnet/roslyn/issues/17090"), WorkItem(19731, "https://github.com/dotnet/roslyn/issues/19731")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SwitchWithConstantPattern()
{
string source = @"
using System;
class Program
{
static void Main(string[] args)
{
M1();
M2();
}
static void M1()
{
switch
(1)
{
case 0 when true:
;
case 1:
Console.Write(1);
break;
case 2:
;
}
}
static void M2()
{
switch
(nameof(M2))
{
case nameof(M1) when true:
;
case nameof(M2):
Console.Write(nameof(M2));
break;
case nameof(Main):
;
}
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugExe);
c.VerifyDiagnostics();
var verifier = CompileAndVerify(c, expectedOutput: "1M2");
verifier.VerifyIL(qualifiedMethodName: "Program.M1", sequencePoints: "Program.M1", source: source,
expectedIL: @"{
// Code size 17 (0x11)
.maxstack 1
.locals init (int V_0,
int V_1)
// sequence point: {
IL_0000: nop
// sequence point: switch ... (1
IL_0001: ldc.i4.1
IL_0002: stloc.1
IL_0003: ldc.i4.1
IL_0004: stloc.0
// sequence point:
IL_0005: br.s IL_0007
// sequence point: Console.Write(1);
IL_0007: ldc.i4.1
IL_0008: call ""void System.Console.Write(int)""
IL_000d: nop
// sequence point: break;
IL_000e: br.s IL_0010
// sequence point: }
IL_0010: ret
}");
verifier.VerifyIL(qualifiedMethodName: "Program.M2", sequencePoints: "Program.M2", source: source,
expectedIL: @"{
// Code size 29 (0x1d)
.maxstack 1
.locals init (string V_0,
string V_1)
// sequence point: {
IL_0000: nop
// sequence point: switch ... (nameof(M2)
IL_0001: ldstr ""M2""
IL_0006: stloc.1
IL_0007: ldstr ""M2""
IL_000c: stloc.0
// sequence point:
IL_000d: br.s IL_000f
// sequence point: Console.Write(nameof(M2));
IL_000f: ldstr ""M2""
IL_0014: call ""void System.Console.Write(string)""
IL_0019: nop
// sequence point: break;
IL_001a: br.s IL_001c
// sequence point: }
IL_001c: ret
}");
// Check the release code generation too.
c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.ReleaseExe);
c.VerifyDiagnostics();
verifier = CompileAndVerify(c, expectedOutput: "1M2");
verifier.VerifyIL("Program.M1",
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldc.i4.1
IL_0001: call ""void System.Console.Write(int)""
IL_0006: ret
}");
verifier.VerifyIL("Program.M2",
@"{
// Code size 11 (0xb)
.maxstack 1
IL_0000: ldstr ""M2""
IL_0005: call ""void System.Console.Write(string)""
IL_000a: ret
}");
}
[WorkItem(19734, "https://github.com/dotnet/roslyn/issues/19734")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SwitchWithConstantGenericPattern_01()
{
string source = @"
using System;
class Program
{
static void Main(string[] args)
{
M1(); // 1
M1(); // 2
M2(); // 3
M2(); // 4
}
static void M1()
{
switch (1)
{
case T t:
Console.Write(1);
break;
case int i:
Console.Write(2);
break;
}
}
static void M2()
{
switch (nameof(M2))
{
case T t:
Console.Write(3);
break;
case string s:
Console.Write(4);
break;
case null:
;
}
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_1);
c.VerifyDiagnostics();
var verifier = CompileAndVerify(c, expectedOutput: "1234");
verifier.VerifyIL(qualifiedMethodName: "Program.M1", sequencePoints: "Program.M1", source: source,
expectedIL: @"{
// Code size 60 (0x3c)
.maxstack 1
.locals init (T V_0, //t
int V_1, //i
int V_2)
// sequence point: {
IL_0000: nop
// sequence point: switch (1)
IL_0001: ldc.i4.1
IL_0002: stloc.2
IL_0003: ldc.i4.1
IL_0004: stloc.1
// sequence point:
IL_0005: ldloc.1
IL_0006: box ""int""
IL_000b: isinst ""T""
IL_0010: brfalse.s IL_0030
IL_0012: ldloc.1
IL_0013: box ""int""
IL_0018: isinst ""T""
IL_001d: unbox.any ""T""
IL_0022: stloc.0
// sequence point:
IL_0023: br.s IL_0025
// sequence point:
IL_0025: br.s IL_0027
// sequence point: Console.Write(1);
IL_0027: ldc.i4.1
IL_0028: call ""void System.Console.Write(int)""
IL_002d: nop
// sequence point: break;
IL_002e: br.s IL_003b
// sequence point:
IL_0030: br.s IL_0032
// sequence point: Console.Write(2);
IL_0032: ldc.i4.2
IL_0033: call ""void System.Console.Write(int)""
IL_0038: nop
// sequence point: break;
IL_0039: br.s IL_003b
// sequence point: }
IL_003b: ret
}");
verifier.VerifyIL(qualifiedMethodName: "Program.M2", sequencePoints: "Program.M2", source: source,
expectedIL: @"{
// Code size 58 (0x3a)
.maxstack 1
.locals init (T V_0, //t
string V_1, //s
string V_2)
// sequence point: {
IL_0000: nop
// sequence point: switch (nameof(M2))
IL_0001: ldstr ""M2""
IL_0006: stloc.2
IL_0007: ldstr ""M2""
IL_000c: stloc.1
// sequence point:
IL_000d: ldloc.1
IL_000e: isinst ""T""
IL_0013: brfalse.s IL_002e
IL_0015: ldloc.1
IL_0016: isinst ""T""
IL_001b: unbox.any ""T""
IL_0020: stloc.0
// sequence point:
IL_0021: br.s IL_0023
// sequence point:
IL_0023: br.s IL_0025
// sequence point: Console.Write(3);
IL_0025: ldc.i4.3
IL_0026: call ""void System.Console.Write(int)""
IL_002b: nop
// sequence point: break;
IL_002c: br.s IL_0039
// sequence point:
IL_002e: br.s IL_0030
// sequence point: Console.Write(4);
IL_0030: ldc.i4.4
IL_0031: call ""void System.Console.Write(int)""
IL_0036: nop
// sequence point: break;
IL_0037: br.s IL_0039
// sequence point: }
IL_0039: ret
}");
// Check the release code generation too.
c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular7_1);
c.VerifyDiagnostics();
verifier = CompileAndVerify(c, expectedOutput: "1234");
verifier.VerifyIL("Program.M1",
@"{
// Code size 29 (0x1d)
.maxstack 1
.locals init (int V_0) //i
IL_0000: ldc.i4.1
IL_0001: stloc.0
IL_0002: ldloc.0
IL_0003: box ""int""
IL_0008: isinst ""T""
IL_000d: brfalse.s IL_0016
IL_000f: ldc.i4.1
IL_0010: call ""void System.Console.Write(int)""
IL_0015: ret
IL_0016: ldc.i4.2
IL_0017: call ""void System.Console.Write(int)""
IL_001c: ret
}");
verifier.VerifyIL("Program.M2",
@"{
// Code size 28 (0x1c)
.maxstack 1
.locals init (string V_0) //s
IL_0000: ldstr ""M2""
IL_0005: stloc.0
IL_0006: ldloc.0
IL_0007: isinst ""T""
IL_000c: brfalse.s IL_0015
IL_000e: ldc.i4.3
IL_000f: call ""void System.Console.Write(int)""
IL_0014: ret
IL_0015: ldc.i4.4
IL_0016: call ""void System.Console.Write(int)""
IL_001b: ret
}");
}
[WorkItem(19734, "https://github.com/dotnet/roslyn/issues/19734")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SwitchWithConstantGenericPattern_02()
{
string source = @"
using System;
class Program
{
static void Main(string[] args)
{
M2(); // 6
M2(); // 6
}
static void M2()
{
const string x = null;
switch (x)
{
case T t:
;
case string s:
;
case null:
Console.Write(6);
break;
}
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugExe, parseOptions: TestOptions.Regular7_1);
c.VerifyDiagnostics();
var verifier = CompileAndVerify(c, expectedOutput: "66");
verifier.VerifyIL(qualifiedMethodName: "Program.M2", sequencePoints: "Program.M2", source: source,
expectedIL: @"{
// Code size 17 (0x11)
.maxstack 1
.locals init (T V_0, //t
string V_1, //s
string V_2,
string V_3)
// sequence point: {
IL_0000: nop
// sequence point: switch (x)
IL_0001: ldnull
IL_0002: stloc.3
IL_0003: ldnull
IL_0004: stloc.2
// sequence point:
IL_0005: br.s IL_0007
// sequence point: Console.Write(6);
IL_0007: ldc.i4.6
IL_0008: call ""void System.Console.Write(int)""
IL_000d: nop
// sequence point: break;
IL_000e: br.s IL_0010
// sequence point: }
IL_0010: ret
}");
// Check the release code generation too.
c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.ReleaseExe, parseOptions: TestOptions.Regular7_1);
c.VerifyDiagnostics();
verifier = CompileAndVerify(c, expectedOutput: "66");
verifier.VerifyIL("Program.M2",
@"{
// Code size 7 (0x7)
.maxstack 1
IL_0000: ldc.i4.6
IL_0001: call ""void System.Console.Write(int)""
IL_0006: ret
}");
}
#endregion
#region DoStatement
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void DoStatement()
{
var source = @"using System;
public class SeqPointForWhile
{
public static void Main()
{
SeqPointForWhile obj = new SeqPointForWhile();
obj.While(234);
}
int field;
public void While(int p)
{
do
{
p = (int)(p / 2);
if (p > 100)
{
continue;
}
else if (p > 10)
{
field = 1;
}
else
{
break;
}
} while (p > 0); // SeqPt should be generated for [while (p > 0);]
field = -1;
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb(@"
");
}
#endregion
#region Constructor
[WorkItem(538317, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538317")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ConstructorSequencePoints1()
{
var source = @"namespace NS
{
public class MyClass
{
int intTest;
public MyClass()
{
intTest = 123;
}
public MyClass(params int[] values)
{
intTest = values[0] + values[1] + values[2];
}
public static int Main()
{
int intI = 1, intJ = 8;
int intK = 3;
// Can't step into Ctor
MyClass mc = new MyClass();
// Can't step into Ctor
mc = new MyClass(intI, intJ, intK);
return mc.intTest - 12;
}
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
// Dev10 vs. Roslyn
//
// Default Ctor (no param)
// Dev10 Roslyn
// ======================================================================================
// Code size 18 (0x12) // Code size 16 (0x10)
// .maxstack 8 .maxstack 8
//* IL_0000: ldarg.0 *IL_0000: ldarg.0
// IL_0001: call IL_0001: callvirt
// instance void [mscorlib]System.Object::.ctor() instance void [mscorlib]System.Object::.ctor()
// IL_0006: nop *IL_0006: nop
//* IL_0007: nop
//* IL_0008: ldarg.0 *IL_0007: ldarg.0
// IL_0009: ldc.i4.s 123 IL_0008: ldc.i4.s 123
// IL_000b: stfld int32 NS.MyClass::intTest IL_000a: stfld int32 NS.MyClass::intTest
// IL_0010: nop
//* IL_0011: ret *IL_000f: ret
// -----------------------------------------------------------------------------------------
// SeqPoint: 0, 7 ,8, 0x10 0, 6, 7, 0xf
c.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ConstructorSequencePoints2()
{
TestSequencePoints(
@"using System;
class D
{
public D() : [|base()|]
{
}
}", TestOptions.DebugDll);
TestSequencePoints(
@"using System;
class D
{
static D()
[|{|]
}
}", TestOptions.DebugDll);
TestSequencePoints(
@"using System;
class A : Attribute {}
class D
{
[A]
public D() : [|base()|]
{
}
}", TestOptions.DebugDll);
TestSequencePoints(
@"using System;
class A : Attribute {}
class D
{
[A]
public D()
: [|base()|]
{
}
}", TestOptions.DebugDll);
TestSequencePoints(
@"using System;
class A : Attribute {}
class C { }
class D
{
[A]
[|public D()|]
{
}
}", TestOptions.DebugDll);
}
#endregion
#region Destructor
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void Destructors()
{
var source = @"
using System;
public class Base
{
~Base()
{
Console.WriteLine();
}
}
public class Derived : Base
{
~Derived()
{
Console.WriteLine();
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb(@"
");
}
#endregion
#region Field and Property Initializers
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void TestPartialClassFieldInitializers()
{
var text1 = @"
public partial class C
{
int x = 1;
}
";
var text2 = @"
public partial class C
{
int y = 1;
static void Main()
{
C c = new C();
}
}
";
//Having a unique name here may be important. The infrastructure of the pdb to xml conversion
//loads the assembly into the ReflectionOnlyLoadFrom context.
//So it's probably a good idea to have a new name for each assembly.
var compilation = CreateCompilation(new SyntaxTree[] { Parse(text1, "a.cs"), Parse(text2, "b.cs") });
compilation.VerifyPdb("C..ctor", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void TestPartialClassFieldInitializersWithLineDirectives()
{
var text1 = @"
using System;
public partial class C
{
int x = 1;
#line 12 ""foo.cs""
int z = Math.Abs(-3);
int w = Math.Abs(4);
#line 17 ""bar.cs""
double zed = Math.Sin(5);
}
#pragma checksum ""mah.cs"" ""{406EA660-64CF-4C82-B6F0-42D48172A799}"" ""ab007f1d23d9""
";
var text2 = @"
using System;
public partial class C
{
int y = 1;
int x2 = 1;
#line 12 ""foo2.cs""
int z2 = Math.Abs(-3);
int w2 = Math.Abs(4);
}
";
var text3 = @"
using System;
public partial class C
{
#line 112 ""mah.cs""
int y3 = 1;
int x3 = 1;
int z3 = Math.Abs(-3);
#line default
int w3 = Math.Abs(4);
double zed3 = Math.Sin(5);
C() {
Console.WriteLine(""hi"");
}
static void Main()
{
C c = new C();
}
}
";
//Having a unique name here may be important. The infrastructure of the pdb to xml conversion
//loads the assembly into the ReflectionOnlyLoadFrom context.
//So it's probably a good idea to have a new name for each assembly.
var compilation = CreateCompilation(new[] { Parse(text1, "a.cs"), Parse(text2, "b.cs"), Parse(text3, "a.cs") }, options: TestOptions.DebugDll);
compilation.VerifyPdb("C..ctor", @"
");
}
[WorkItem(543313, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/543313")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void TestFieldInitializerExpressionLambda()
{
var source = @"
class C
{
int x = ((System.Func)(z => z))(1);
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb(@"
1
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void FieldInitializerSequencePointSpans()
{
var source = @"
class C
{
int x = 1, y = 2;
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb(@"
");
}
#endregion
#region Auto-Property
[WorkItem(820806, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/820806")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void BreakpointForAutoImplementedProperty()
{
var source = @"
public class C
{
public static int AutoProp1 { get; private set; }
internal string AutoProp2 { get; set; }
internal protected C AutoProp3 { internal get; set; }
}
";
var comp = CreateCompilation(source, options: TestOptions.DebugDll);
comp.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void PropertyDeclaration()
{
TestSequencePoints(
@"using System;
public class C
{
int P { [|get;|] set; }
}", TestOptions.DebugDll);
TestSequencePoints(
@"using System;
public class C
{
int P { get; [|set;|] }
}", TestOptions.DebugDll);
TestSequencePoints(
@"using System;
public class C
{
int P { get [|{|] return 0; } }
}", TestOptions.DebugDll);
TestSequencePoints(
@"using System;
public class C
{
int P { get; } = [|int.Parse(""42"")|];
}", TestOptions.DebugDll, TestOptions.Regular);
}
#endregion
#region ReturnStatement
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void Return_Implicit()
{
var source = @"class C
{
static void Main()
{
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C.Main", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void Return_Explicit()
{
var source = @"class C
{
static void Main()
{
return;
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C.Main", @"
");
}
[WorkItem(538298, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/538298")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void RegressSeqPtEndOfMethodAfterReturn()
{
var source = @"using System;
public class SeqPointAfterReturn
{
public static int Main()
{
int ret = 0;
ReturnVoid(100);
if (field != ""Even"")
ret = 1;
ReturnVoid(99);
if (field != ""Odd"")
ret = ret + 1;
string rets = ReturnValue(101);
if (rets != ""Odd"")
ret = ret + 1;
rets = ReturnValue(102);
if (rets != ""Even"")
ret = ret + 1;
return ret;
}
static string field;
public static void ReturnVoid(int p)
{
int x = (int)(p % 2);
if (x == 0)
{
field = ""Even"";
}
else
{
field = ""Odd"";
}
}
public static string ReturnValue(int p)
{
int x = (int)(p % 2);
if (x == 0)
{
return ""Even"";
}
else
{
return ""Odd"";
}
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
// Expected are current actual output plus Two extra expected SeqPt:
//
//
//
// Note: NOT include other differences between Roslyn and Dev10, as they are filed in separated bugs
c.VerifyPdb(@"
");
}
#endregion
#region Exception Handling
[WorkItem(542064, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/542064")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ExceptionHandling()
{
var source = @"
class Test
{
static int Main()
{
int ret = 0; // stop 1
try
{ // stop 2
throw new System.Exception(); // stop 3
}
catch (System.Exception e) // stop 4
{ // stop 5
ret = 1; // stop 6
}
try
{ // stop 7
throw new System.Exception(); // stop 8
}
catch // stop 9
{ // stop 10
return ret; // stop 11
}
}
}
";
// Dev12 inserts an additional sequence point on catch clause, just before
// the exception object is assigned to the variable. We don't place that sequence point.
// Also the scope of he exception variable is different.
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("Test.Main", @"
");
}
[WorkItem(2911, "https://github.com/dotnet/roslyn/issues/2911")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ExceptionHandling_Filter_Debug1()
{
var source = @"
using System;
using System.IO;
class Test
{
static string filter(Exception e)
{
return null;
}
static void Main()
{
try
{
throw new InvalidOperationException();
}
catch (IOException e) when (filter(e) != null)
{
Console.WriteLine();
}
catch (Exception e) when (filter(e) != null)
{
Console.WriteLine();
}
}
}
";
var v = CompileAndVerify(CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll));
v.VerifyIL("Test.Main", @"
{
// Code size 89 (0x59)
.maxstack 2
.locals init (System.IO.IOException V_0, //e
bool V_1,
System.Exception V_2, //e
bool V_3)
-IL_0000: nop
.try
{
-IL_0001: nop
-IL_0002: newobj ""System.InvalidOperationException..ctor()""
IL_0007: throw
}
filter
{
~IL_0008: isinst ""System.IO.IOException""
IL_000d: dup
IL_000e: brtrue.s IL_0014
IL_0010: pop
IL_0011: ldc.i4.0
IL_0012: br.s IL_0023
IL_0014: stloc.0
-IL_0015: ldloc.0
IL_0016: call ""string Test.filter(System.Exception)""
IL_001b: ldnull
IL_001c: cgt.un
IL_001e: stloc.1
~IL_001f: ldloc.1
IL_0020: ldc.i4.0
IL_0021: cgt.un
IL_0023: endfilter
} // end filter
{ // handler
~IL_0025: pop
-IL_0026: nop
-IL_0027: call ""void System.Console.WriteLine()""
IL_002c: nop
-IL_002d: nop
IL_002e: leave.s IL_0058
}
filter
{
~IL_0030: isinst ""System.Exception""
IL_0035: dup
IL_0036: brtrue.s IL_003c
IL_0038: pop
IL_0039: ldc.i4.0
IL_003a: br.s IL_004b
IL_003c: stloc.2
-IL_003d: ldloc.2
IL_003e: call ""string Test.filter(System.Exception)""
IL_0043: ldnull
IL_0044: cgt.un
IL_0046: stloc.3
~IL_0047: ldloc.3
IL_0048: ldc.i4.0
IL_0049: cgt.un
IL_004b: endfilter
} // end filter
{ // handler
~IL_004d: pop
-IL_004e: nop
-IL_004f: call ""void System.Console.WriteLine()""
IL_0054: nop
-IL_0055: nop
IL_0056: leave.s IL_0058
}
-IL_0058: ret
}
", sequencePoints: "Test.Main");
v.VerifyPdb("Test.Main", @"
");
}
[WorkItem(2911, "https://github.com/dotnet/roslyn/issues/2911")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ExceptionHandling_Filter_Debug2()
{
var source = @"
class Test
{
static void Main()
{
try
{
throw new System.Exception();
}
catch when (F())
{
System.Console.WriteLine();
}
}
private static bool F()
{
return true;
}
}
";
var v = CompileAndVerify(CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll));
v.VerifyIL("Test.Main", @"
{
// Code size 33 (0x21)
.maxstack 2
.locals init (bool V_0)
-IL_0000: nop
.try
{
-IL_0001: nop
-IL_0002: newobj ""System.Exception..ctor()""
IL_0007: throw
}
filter
{
~IL_0008: pop
-IL_0009: call ""bool Test.F()""
IL_000e: stloc.0
~IL_000f: ldloc.0
IL_0010: ldc.i4.0
IL_0011: cgt.un
IL_0013: endfilter
} // end filter
{ // handler
~IL_0015: pop
-IL_0016: nop
-IL_0017: call ""void System.Console.WriteLine()""
IL_001c: nop
-IL_001d: nop
IL_001e: leave.s IL_0020
}
-IL_0020: ret
}
", sequencePoints: "Test.Main");
v.VerifyPdb("Test.Main", @"
");
}
[WorkItem(2911, "https://github.com/dotnet/roslyn/issues/2911")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ExceptionHandling_Filter_Debug3()
{
var source = @"
class Test
{
static bool a = true;
static void Main()
{
try
{
throw new System.Exception();
}
catch when (a)
{
System.Console.WriteLine();
}
}
}
";
var v = CompileAndVerify(CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll));
v.VerifyIL("Test.Main", @"
{
// Code size 33 (0x21)
.maxstack 2
.locals init (bool V_0)
-IL_0000: nop
.try
{
-IL_0001: nop
-IL_0002: newobj ""System.Exception..ctor()""
IL_0007: throw
}
filter
{
~IL_0008: pop
-IL_0009: ldsfld ""bool Test.a""
IL_000e: stloc.0
~IL_000f: ldloc.0
IL_0010: ldc.i4.0
IL_0011: cgt.un
IL_0013: endfilter
} // end filter
{ // handler
~IL_0015: pop
-IL_0016: nop
-IL_0017: call ""void System.Console.WriteLine()""
IL_001c: nop
-IL_001d: nop
IL_001e: leave.s IL_0020
}
-IL_0020: ret
}
", sequencePoints: "Test.Main");
v.VerifyPdb("Test.Main", @"
");
}
[WorkItem(2911, "https://github.com/dotnet/roslyn/issues/2911")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ExceptionHandling_Filter_Release3()
{
var source = @"
class Test
{
static bool a = true;
static void Main()
{
try
{
throw new System.Exception();
}
catch when (a)
{
System.Console.WriteLine();
}
}
}
";
var v = CompileAndVerify(CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.ReleaseDll));
v.VerifyIL("Test.Main", @"
{
// Code size 26 (0x1a)
.maxstack 2
.try
{
-IL_0000: newobj ""System.Exception..ctor()""
IL_0005: throw
}
filter
{
~IL_0006: pop
-IL_0007: ldsfld ""bool Test.a""
IL_000c: ldc.i4.0
IL_000d: cgt.un
IL_000f: endfilter
} // end filter
{ // handler
~IL_0011: pop
-IL_0012: call ""void System.Console.WriteLine()""
-IL_0017: leave.s IL_0019
}
-IL_0019: ret
}
", sequencePoints: "Test.Main");
v.VerifyPdb("Test.Main", @"
");
}
[WorkItem(778655, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/778655")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void BranchToStartOfTry()
{
string source = @"
using System;
using System.Collections.Generic;
class Program
{
static void Main(string[] args)
{
string str = null;
bool isEmpty = string.IsNullOrEmpty(str);
// isEmpty is always true here, so it should never go thru this if statement.
if (!isEmpty)
{
throw new Exception();
}
try
{
Console.WriteLine();
}
catch
{
}
}
}
";
// Note the hidden sequence point @IL_0019.
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb(@"
");
}
#endregion
#region UsingStatement
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void UsingStatement()
{
var source = @"
public class DisposableClass : System.IDisposable
{
private readonly string name;
public DisposableClass(string name)
{
this.name = name;
System.Console.WriteLine(""Creating "" + name);
}
public void Dispose()
{
System.Console.WriteLine(""Disposing "" + name);
}
}
class C
{
static void Main()
{
using (DisposableClass a = new DisposableClass(""A""), b = new DisposableClass(""B""))
System.Console.WriteLine(""First"");
using (DisposableClass c = new DisposableClass(""C""), d = new DisposableClass(""D""))
{
System.Console.WriteLine(""Second"");
}
using (null)
{
}
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C.Main", @"
");
}
[WorkItem(18844, "https://github.com/dotnet/roslyn/issues/18844")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void UsingStatement_EmbeddedConditional()
{
var source = @"
class C
{
bool F()
{
bool x = true;
bool value = false;
using (var stream = new System.IO.MemoryStream())
if (x)
{
value = true;
}
else
value = false;
return value;
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
var v = CompileAndVerify(c);
v.VerifyIL("C.F", @"
{
// Code size 45 (0x2d)
.maxstack 1
.locals init (bool V_0, //x
bool V_1, //value
System.IO.MemoryStream V_2, //stream
bool V_3,
bool V_4)
// sequence point: {
IL_0000: nop
// sequence point: bool x = true;
IL_0001: ldc.i4.1
IL_0002: stloc.0
// sequence point: bool value = false;
IL_0003: ldc.i4.0
IL_0004: stloc.1
// sequence point: var stream = new System.IO.MemoryStream()
IL_0005: newobj ""System.IO.MemoryStream..ctor()""
IL_000a: stloc.2
.try
{
// sequence point: if (x)
IL_000b: ldloc.0
IL_000c: stloc.3
// sequence point:
IL_000d: ldloc.3
IL_000e: brfalse.s IL_0016
// sequence point: {
IL_0010: nop
// sequence point: value = true;
IL_0011: ldc.i4.1
IL_0012: stloc.1
// sequence point: }
IL_0013: nop
IL_0014: br.s IL_0018
// sequence point: value = false;
IL_0016: ldc.i4.0
IL_0017: stloc.1
// sequence point:
IL_0018: leave.s IL_0025
}
finally
{
// sequence point:
IL_001a: ldloc.2
IL_001b: brfalse.s IL_0024
IL_001d: ldloc.2
IL_001e: callvirt ""void System.IDisposable.Dispose()""
IL_0023: nop
// sequence point:
IL_0024: endfinally
}
// sequence point: return value;
IL_0025: ldloc.1
IL_0026: stloc.s V_4
IL_0028: br.s IL_002a
// sequence point: }
IL_002a: ldloc.s V_4
IL_002c: ret
}
", sequencePoints: "C.F", source: source);
}
[WorkItem(18844, "https://github.com/dotnet/roslyn/issues/18844")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void UsingStatement_EmbeddedConditional2()
{
var source = @"
class C
{
bool F()
{
bool x = true;
bool value = false;
using (var stream = new System.IO.MemoryStream())
if (x)
{
value = true;
}
else
{
value = false;
}
return value;
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
var v = CompileAndVerify(c);
v.VerifyIL("C.F", @"
{
// Code size 47 (0x2f)
.maxstack 1
.locals init (bool V_0, //x
bool V_1, //value
System.IO.MemoryStream V_2, //stream
bool V_3,
bool V_4)
// sequence point: {
IL_0000: nop
// sequence point: bool x = true;
IL_0001: ldc.i4.1
IL_0002: stloc.0
// sequence point: bool value = false;
IL_0003: ldc.i4.0
IL_0004: stloc.1
// sequence point: var stream = new System.IO.MemoryStream()
IL_0005: newobj ""System.IO.MemoryStream..ctor()""
IL_000a: stloc.2
.try
{
// sequence point: if (x)
IL_000b: ldloc.0
IL_000c: stloc.3
// sequence point:
IL_000d: ldloc.3
IL_000e: brfalse.s IL_0016
// sequence point: {
IL_0010: nop
// sequence point: value = true;
IL_0011: ldc.i4.1
IL_0012: stloc.1
// sequence point: }
IL_0013: nop
IL_0014: br.s IL_001a
// sequence point: {
IL_0016: nop
// sequence point: value = false;
IL_0017: ldc.i4.0
IL_0018: stloc.1
// sequence point: }
IL_0019: nop
// sequence point:
IL_001a: leave.s IL_0027
}
finally
{
// sequence point:
IL_001c: ldloc.2
IL_001d: brfalse.s IL_0026
IL_001f: ldloc.2
IL_0020: callvirt ""void System.IDisposable.Dispose()""
IL_0025: nop
// sequence point:
IL_0026: endfinally
}
// sequence point: return value;
IL_0027: ldloc.1
IL_0028: stloc.s V_4
IL_002a: br.s IL_002c
// sequence point: }
IL_002c: ldloc.s V_4
IL_002e: ret
}
", sequencePoints: "C.F", source: source);
}
[WorkItem(18844, "https://github.com/dotnet/roslyn/issues/18844")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void UsingStatement_EmbeddedWhile()
{
var source = @"
class C
{
void F(bool x)
{
using (var stream = new System.IO.MemoryStream())
while (x)
x = false;
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
var v = CompileAndVerify(c);
v.VerifyIL("C.F", @"
{
// Code size 31 (0x1f)
.maxstack 1
.locals init (System.IO.MemoryStream V_0, //stream
bool V_1)
// sequence point: {
IL_0000: nop
// sequence point: var stream = new System.IO.MemoryStream()
IL_0001: newobj ""System.IO.MemoryStream..ctor()""
IL_0006: stloc.0
.try
{
// sequence point:
IL_0007: br.s IL_000c
// sequence point: x = false;
IL_0009: ldc.i4.0
IL_000a: starg.s V_1
// sequence point: while (x)
IL_000c: ldarg.1
IL_000d: stloc.1
// sequence point:
IL_000e: ldloc.1
IL_000f: brtrue.s IL_0009
IL_0011: leave.s IL_001e
}
finally
{
// sequence point:
IL_0013: ldloc.0
IL_0014: brfalse.s IL_001d
IL_0016: ldloc.0
IL_0017: callvirt ""void System.IDisposable.Dispose()""
IL_001c: nop
// sequence point:
IL_001d: endfinally
}
// sequence point: }
IL_001e: ret
}
", sequencePoints: "C.F", source: source);
}
[WorkItem(18844, "https://github.com/dotnet/roslyn/issues/18844")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void UsingStatement_EmbeddedFor()
{
var source = @"
class C
{
void F(bool x)
{
using (var stream = new System.IO.MemoryStream())
for ( ; x == true; )
x = false;
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
var v = CompileAndVerify(c);
v.VerifyIL("C.F", @"
{
// Code size 31 (0x1f)
.maxstack 1
.locals init (System.IO.MemoryStream V_0, //stream
bool V_1)
// sequence point: {
IL_0000: nop
// sequence point: var stream = new System.IO.MemoryStream()
IL_0001: newobj ""System.IO.MemoryStream..ctor()""
IL_0006: stloc.0
.try
{
// sequence point:
IL_0007: br.s IL_000c
// sequence point: x = false;
IL_0009: ldc.i4.0
IL_000a: starg.s V_1
// sequence point: x == true
IL_000c: ldarg.1
IL_000d: stloc.1
// sequence point:
IL_000e: ldloc.1
IL_000f: brtrue.s IL_0009
IL_0011: leave.s IL_001e
}
finally
{
// sequence point:
IL_0013: ldloc.0
IL_0014: brfalse.s IL_001d
IL_0016: ldloc.0
IL_0017: callvirt ""void System.IDisposable.Dispose()""
IL_001c: nop
// sequence point:
IL_001d: endfinally
}
// sequence point: }
IL_001e: ret
}
", sequencePoints: "C.F", source: source);
}
[WorkItem(18844, "https://github.com/dotnet/roslyn/issues/18844")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void LockStatement_EmbeddedIf()
{
var source = @"
class C
{
void F(bool x)
{
string y = """";
lock (y)
if (!x)
System.Console.Write(1);
else
System.Console.Write(2);
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
var v = CompileAndVerify(c);
v.VerifyIL("C.F", @"
{
// Code size 58 (0x3a)
.maxstack 2
.locals init (string V_0, //y
string V_1,
bool V_2,
bool V_3)
// sequence point: {
IL_0000: nop
// sequence point: string y = """";
IL_0001: ldstr """"
IL_0006: stloc.0
// sequence point: lock (y)
IL_0007: ldloc.0
IL_0008: stloc.1
IL_0009: ldc.i4.0
IL_000a: stloc.2
.try
{
IL_000b: ldloc.1
IL_000c: ldloca.s V_2
IL_000e: call ""void System.Threading.Monitor.Enter(object, ref bool)""
IL_0013: nop
// sequence point: if (!x)
IL_0014: ldarg.1
IL_0015: ldc.i4.0
IL_0016: ceq
IL_0018: stloc.3
// sequence point:
IL_0019: ldloc.3
IL_001a: brfalse.s IL_0025
// sequence point: System.Console.Write(1);
IL_001c: ldc.i4.1
IL_001d: call ""void System.Console.Write(int)""
IL_0022: nop
IL_0023: br.s IL_002c
// sequence point: System.Console.Write(2);
IL_0025: ldc.i4.2
IL_0026: call ""void System.Console.Write(int)""
IL_002b: nop
// sequence point:
IL_002c: leave.s IL_0039
}
finally
{
// sequence point:
IL_002e: ldloc.2
IL_002f: brfalse.s IL_0038
IL_0031: ldloc.1
IL_0032: call ""void System.Threading.Monitor.Exit(object)""
IL_0037: nop
// sequence point:
IL_0038: endfinally
}
// sequence point: }
IL_0039: ret
}
", sequencePoints: "C.F", source: source);
}
#endregion
// LockStatement tested in CodeGenLock
#region Anonymous Type
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void AnonymousType_Empty()
{
var source = @"
class Program
{
static void Main(string[] args)
{
var o = new {};
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void AnonymousType_NonEmpty()
{
var source = @"
class Program
{
static void Main(string[] args)
{
var o = new { a = 1 };
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb(@"
");
}
#endregion
#region FixedStatement
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void FixedStatementSingleAddress()
{
var source = @"
using System;
unsafe class C
{
int x;
static void Main()
{
C c = new C();
fixed (int* p = &c.x)
{
*p = 1;
}
Console.WriteLine(c.x);
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.UnsafeDebugExe);
c.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void FixedStatementSingleString()
{
var source = @"
using System;
unsafe class C
{
static void Main()
{
fixed (char* p = ""hello"")
{
Console.WriteLine(*p);
}
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.UnsafeDebugDll);
c.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void FixedStatementSingleArray()
{
var source = @"
using System;
unsafe class C
{
int[] a = new int[1];
static void Main()
{
C c = new C();
Console.Write(c.a[0]);
fixed (int* p = c.a)
{
(*p)++;
}
Console.Write(c.a[0]);
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.UnsafeDebugExe);
c.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void FixedStatementMultipleAddresses()
{
var source = @"
using System;
unsafe class C
{
int x;
int y;
static void Main()
{
C c = new C();
fixed (int* p = &c.x, q = &c.y)
{
*p = 1;
*q = 2;
}
Console.WriteLine(c.x + c.y);
}
}
";
// NOTE: stop on each declarator.
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.UnsafeDebugExe);
c.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void FixedStatementMultipleStrings()
{
var source = @"
using System;
unsafe class C
{
static void Main()
{
fixed (char* p = ""hello"", q = ""goodbye"")
{
Console.Write(*p);
Console.Write(*q);
}
}
}
";
// NOTE: stop on each declarator.
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.UnsafeDebugDll);
c.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void FixedStatementMultipleArrays()
{
var source = @"
using System;
unsafe class C
{
int[] a = new int[1];
int[] b = new int[1];
static void Main()
{
C c = new C();
Console.Write(c.a[0]);
Console.Write(c.b[0]);
fixed (int* p = c.a, q = c.b)
{
*p = 1;
*q = 2;
}
Console.Write(c.a[0]);
Console.Write(c.b[0]);
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.UnsafeDebugExe);
c.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void FixedStatementMultipleMixed()
{
var source = @"
using System;
unsafe class C
{
char c = 'a';
char[] a = new char[1];
static void Main()
{
C c = new C();
fixed (char* p = &c.c, q = c.a, r = ""hello"")
{
Console.Write((int)*p);
Console.Write((int)*q);
Console.Write((int)*r);
}
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.UnsafeDebugDll);
c.VerifyPdb(@"
");
}
#endregion
#region Line Directives
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void LineDirective()
{
var source = @"
#line 50 ""foo.cs""
using System;
unsafe class C
{
static void Main()
{
Console.Write(1);
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.UnsafeDebugExe);
c.VerifyPdb(@"
");
}
[WorkItem(544917, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/544917")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void DisabledLineDirective()
{
var source = @"
#if false
#line 50 ""foo.cs""
#endif
using System;
unsafe class C
{
static void Main()
{
Console.Write(1);
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.UnsafeDebugExe);
c.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void TestLineDirectivesHidden()
{
var text1 = @"
using System;
public class C
{
public void Foo()
{
foreach (var x in new int[] { 1, 2, 3, 4 })
{
Console.WriteLine(x);
}
#line hidden
foreach (var x in new int[] { 1, 2, 3, 4 })
{
Console.WriteLine(x);
}
#line default
foreach (var x in new int[] { 1, 2, 3, 4 })
{
Console.WriteLine(x);
}
}
}
";
var compilation = CreateCompilation(text1, options: TestOptions.DebugDll);
compilation.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void HiddenMethods()
{
var src = @"
using System;
class C
{
#line hidden
public static void H()
{
F();
}
#line default
public static void G()
{
F();
}
#line hidden
public static void F()
{
{
const int z = 1;
var (x, y) = (1,2);
Console.WriteLine(x + z);
}
{
dynamic x = 1;
Console.WriteLine(x);
}
}
}";
var c = CreateCompilationWithMscorlib40AndSystemCore(src, references: new[] { CSharpRef, ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugDll);
c.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void HiddenEntryPoint()
{
var src = @"
class C
{
#line hidden
public static void Main()
{
}
}";
var c = CreateCompilationWithMscorlib40AndSystemCore(src, references: new[] { CSharpRef, ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugExe);
// Note: Dev10 emitted a hidden sequence point to #line hidden method,
// which enabled the debugger to locate the first user visible sequence point starting from the entry point.
// Roslyn does not emit such sequence point. We could potentially synthesize one but that would defeat the purpose of
// #line hidden directive.
c.VerifyPdb(@"
",
// When converting from Portable to Windows the PDB writer doesn't create an entry for the Main method
// and thus there is no entry point record either.
options: PdbValidationOptions.SkipConversionValidation);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void HiddenIterator()
{
var src = @"
using System;
using System.Collections.Generic;
class C
{
public static void Main()
{
F();
}
#line hidden
public static IEnumerable F()
{
{
const int z = 1;
var (x, y) = (1,2);
Console.WriteLine(x + z);
}
{
dynamic x = 1;
Console.WriteLine(x);
}
yield return 1;
}
}";
var c = CreateCompilationWithMscorlib40AndSystemCore(src, references: new[] { CSharpRef, ValueTupleRef, SystemRuntimeFacadeRef }, options: TestOptions.DebugDll);
// We don't really need the debug info for kickoff method when the entire iterator method is hidden,
// but it doesn't hurt and removing it would need extra effort that's unnecessary.
c.VerifyPdb(@"
");
}
#endregion
#region Nested Types
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void NestedTypes()
{
string source = @"
using System;
namespace N
{
public class C
{
public class D
{
public class E
{
public static void f(int a)
{
Console.WriteLine();
}
}
}
}
}
";
var c = CreateCompilation(Parse(source, filename: "file.cs"));
c.VerifyPdb(@"
");
}
#endregion
#region Expression Bodied Members
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ExpressionBodiedProperty()
{
var comp = CreateCompilationWithMscorlib45(@"
class C
{
public int P => M();
public int M()
{
return 2;
}
}");
comp.VerifyDiagnostics();
comp.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ExpressionBodiedIndexer()
{
var comp = CreateCompilationWithMscorlib45(@"
using System;
class C
{
public int this[Int32 i] => M();
public int M()
{
return 2;
}
}");
comp.VerifyDiagnostics();
comp.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ExpressionBodiedMethod()
{
var comp = CreateCompilationWithMscorlib45(@"
using System;
class C
{
public Int32 P => 2;
}");
comp.VerifyDiagnostics();
comp.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ExpressionBodiedOperator()
{
var comp = CreateCompilationWithMscorlib45(@"
class C
{
public static C operator ++(C c) => c;
}");
comp.VerifyDiagnostics();
comp.VerifyPdb(@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ExpressionBodiedConversion()
{
var comp = CreateCompilationWithMscorlib45(@"
using System;
class C
{
public static explicit operator C(Int32 i) => new C();
}");
comp.VerifyDiagnostics();
comp.VerifyPdb(@"
");
}
[WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ExpressionBodiedConstructor()
{
var comp = CreateCompilationWithMscorlib45(@"
using System;
class C
{
public int X;
public C(Int32 x) => X = x;
}");
comp.VerifyDiagnostics();
comp.VerifyPdb(@"
");
}
[WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ExpressionBodiedDestructor()
{
var comp = CreateCompilationWithMscorlib45(@"
class C
{
public int X;
~C() => X = 0;
}");
comp.VerifyDiagnostics();
comp.VerifyPdb(@"
");
}
[WorkItem(14438, "https://github.com/dotnet/roslyn/issues/14438")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ExpressionBodiedAccessor()
{
var comp = CreateCompilationWithMscorlib45(@"
class C
{
public int x;
public int X
{
get => x;
set => x = value;
}
public event System.Action E
{
add => x = 1;
remove => x = 0;
}
}");
comp.VerifyDiagnostics();
comp.VerifyPdb(@"
");
}
#endregion
#region Synthesized Methods
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ImportsInLambda()
{
var source =
@"using System.Collections.Generic;
using System.Linq;
class C
{
static void M()
{
System.Action f = () =>
{
var c = new[] { 1, 2, 3 };
c.Select(i => i);
};
f();
}
}";
var c = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugDll, references: new[] { SystemCoreRef });
c.VerifyPdb("C+<>c.b__0_0",
@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ImportsInIterator()
{
var source =
@"using System.Collections.Generic;
using System.Linq;
class C
{
static IEnumerable F()
{
var c = new[] { 1, 2, 3 };
foreach (var i in c.Select(i => i))
{
yield return i;
}
}
}";
var c = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugDll, references: new[] { SystemCoreRef });
c.VerifyPdb("C+d__0.MoveNext",
@"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ImportsInAsync()
{
var source =
@"using System.Linq;
using System.Threading.Tasks;
class C
{
static async Task F()
{
var c = new[] { 1, 2, 3 };
c.Select(i => i);
}
}";
var c = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugDll, references: new[] { SystemCoreRef });
c.VerifyPdb("C+d__0.MoveNext",
@"
");
}
[WorkItem(2501, "https://github.com/dotnet/roslyn/issues/2501")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void ImportsInAsyncLambda()
{
var source =
@"using System.Linq;
class C
{
static void M()
{
System.Action f = async () =>
{
var c = new[] { 1, 2, 3 };
c.Select(i => i);
};
}
}";
var c = CreateCompilationWithMscorlib45(source, options: TestOptions.DebugDll, references: new[] { SystemCoreRef });
c.VerifyPdb("C+<>c.b__0_0",
@"
");
c.VerifyPdb("C+<>c+<b__0_0>d.MoveNext",
@"
");
}
#endregion
#region Patterns
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffset_Pattern()
{
var source = @"class C { bool F(object o) => o is int i && o is 3 && o is bool; }";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C.F", @"
");
}
#endregion
#region Tuples
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffset_TupleDeconstruction()
{
var source = @"class C { int F() { (int a, (_, int c)) = (1, (2, 3)); return a + c; } }";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll, references: s_valueTupleRefs);
c.VerifyPdb("C.F", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void TestDeconstruction()
{
var source = @"
public class C
{
public static (int, int) F() => (1, 2);
public static void Main()
{
int x, y;
(x, y) = F();
System.Console.WriteLine(x + y);
}
}
";
var c = CreateCompilation(source, options: TestOptions.DebugDll);
var v = CompileAndVerify(c);
v.VerifyIL("C.Main", @"
{
// Code size 29 (0x1d)
.maxstack 2
.locals init (int V_0, //x
int V_1) //y
// sequence point: {
IL_0000: nop
// sequence point: (x, y) = F();
IL_0001: call ""(int, int) C.F()""
IL_0006: dup
IL_0007: ldfld ""int System.ValueTuple.Item1""
IL_000c: stloc.0
IL_000d: ldfld ""int System.ValueTuple.Item2""
IL_0012: stloc.1
// sequence point: System.Console.WriteLine(x + y);
IL_0013: ldloc.0
IL_0014: ldloc.1
IL_0015: add
IL_0016: call ""void System.Console.WriteLine(int)""
IL_001b: nop
// sequence point: }
IL_001c: ret
}
", sequencePoints: "C.Main", source: source);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffset_TupleParenthesized()
{
var source = @"class C { int F() { (int, (int, int)) x = (1, (2, 3)); return x.Item1 + x.Item2.Item1 + x.Item2.Item2; } }";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll, references: s_valueTupleRefs);
c.VerifyPdb("C.F", @"
"
);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffset_TupleVarDefined()
{
var source = @"class C { int F() { var x = (1, 2); return x.Item1 + x.Item2; } }";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll, references: s_valueTupleRefs);
c.VerifyPdb("C.F", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffset_TupleIgnoreDeconstructionIfVariableDeclared()
{
var source = @"class C { int F() { (int x, int y) a = (1, 2); return a.Item1 + a.Item2; } }";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll, references: s_valueTupleRefs);
c.VerifyPdb("C.F", @"
");
}
#endregion
#region OutVar
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffset_OutVarInConstructor()
{
var source = @"
class B
{
B(out int z) { z = 2; }
}
class C
{
int F = G(out var v1);
int P => G(out var v2);
C()
: base(out var v3)
{
G(out var v4);
}
int G(out int x)
{
x = 1;
return 2;
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyDiagnostics(
// (9,13): error CS0236: A field initializer cannot reference the non-static field, method, or property 'C.G(out int)'
// int F = G(out var v1);
Diagnostic(ErrorCode.ERR_FieldInitRefNonstatic, "G").WithArguments("C.G(out int)").WithLocation(9, 13),
// (13,7): error CS1729: 'object' does not contain a constructor that takes 1 arguments
// : base(out var v3)
Diagnostic(ErrorCode.ERR_BadCtorArgCount, "base").WithArguments("object", "1").WithLocation(13, 7));
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffset_OutVarInMethod()
{
var source = @"class C { int G(out int x) { int z = 1; G(out var y); G(out var w); return x = y; } }";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C.G", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffset_OutVarInInitializers_01()
{
var source =
@"
class C : A
{
int x = G(out var x);
int y {get;} = G(out var y);
C() : base(G(out var z))
{
}
static int G(out int x)
{
throw null;
}
}
class A
{
public A(int x) {}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C..ctor", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffset_OutVarInInitializers_02()
{
var source =
@"
class C : A
{
C() : base(G(out var x))
{
int y = 1;
y++;
}
static int G(out int x)
{
throw null;
}
}
class A
{
public A(int x) {}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C..ctor", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffset_OutVarInInitializers_03()
{
var source =
@"
class C : A
{
C() : base(G(out var x))
=> G(out var y);
static int G(out int x)
{
throw null;
}
}
class A
{
public A(int x) {}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C..ctor", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffset_OutVarInInitializers_04()
{
var source =
@"
class C
{
static int G(out int x)
{
throw null;
}
static int F(System.Func x)
{
throw null;
}
C()
{
}
#line 2000
int y1 = G(out var z) + F(() => z);
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C..ctor", @"
2
");
c.VerifyPdb("C+<>c__DisplayClass2_0.<.ctor>b__0", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffset_OutVarInInitializers_05()
{
var source =
@"
class C
{
static int G(out int x)
{
throw null;
}
static int F(System.Func x)
{
throw null;
}
#line 2000
int y1 { get; } = G(out var z) + F(() => z);
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C..ctor", @"
5
");
c.VerifyPdb("C+<>c__DisplayClass5_0.<.ctor>b__0", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffset_OutVarInInitializers_06()
{
var source =
@"
class C
{
static int G(out int x)
{
throw null;
}
static int F(System.Func x)
{
throw null;
}
#line 2000
int y1 = G(out var z) + F(() => z), y2 = G(out var u) + F(() => u);
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C..ctor", @"
4
");
c.VerifyPdb("C+<>c__DisplayClass4_0.<.ctor>b__0", @"
");
c.VerifyPdb("C+<>c__DisplayClass4_1.<.ctor>b__1", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffset_OutVarInInitializers_07()
{
var source =
@"
class C : A
{
#line 2000
C() : base(G(out var z)+ F(() => z))
{
}
static int G(out int x)
{
throw null;
}
static int F(System.Func x)
{
throw null;
}
}
class A
{
public A(int x) {}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C..ctor", @"
0
");
c.VerifyPdb("C+<>c__DisplayClass0_0.<.ctor>b__0", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffset_OutVarInQuery_01()
{
var source =
@"
using System.Linq;
class C
{
C()
{
var q = from a in new [] {1}
where
G(out var x1) > a
select a;
}
static int G(out int x)
{
throw null;
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C..ctor", @"
0
");
c.VerifyPdb("C+<>c.<.ctor>b__0_0", @"
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SyntaxOffset_OutVarInQuery_02()
{
var source =
@"
using System.Linq;
class C
{
C()
#line 2000
{
var q = from a in new [] {1}
where
G(out var x1) > F(() => x1)
select a;
}
static int G(out int x)
{
throw null;
}
static int F(System.Func x)
{
throw null;
}
}
";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb("C..ctor", @"
0
");
c.VerifyPdb("C+<>c.<.ctor>b__0_0", @"
");
c.VerifyPdb("C+<>c__DisplayClass0_0.<.ctor>b__1", @"
");
}
#endregion
[WorkItem(4370, "https://github.com/dotnet/roslyn/issues/4370")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void HeadingHiddenSequencePointsPickUpDocumentFromVisibleSequencePoint()
{
var source =
@"#line 1 ""C:\Async.cs""
#pragma checksum ""C:\Async.cs"" ""{ff1816ec-aa5e-4d10-87f7-6f4963833460}"" ""DBEB2A067B2F0E0D678A002C587A2806056C3DCE""
using System.Threading.Tasks;
public class C
{
public async void M1()
{
}
}
";
var tree = SyntaxFactory.ParseSyntaxTree(source, encoding: Encoding.UTF8, path: "HIDDEN.cs");
var c = CSharpCompilation.Create("Compilation", new[] { tree }, new[] { MscorlibRef_v46 }, options: TestOptions.DebugDll.WithDebugPlusMode(true));
c.VerifyPdb(
@"
");
}
[WorkItem(12923, "https://github.com/dotnet/roslyn/issues/12923")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void SequencePointsForConstructorWithHiddenInitializer()
{
string initializerSource = @"
#line hidden
partial class C
{
int i = 42;
}
";
string constructorSource = @"
partial class C
{
C()
{
}
}
";
var c = CreateCompilation(
new[] { Parse(initializerSource, "initializer.cs"), Parse(constructorSource, "constructor.cs") },
options: TestOptions.DebugDll);
c.VerifyPdb(@"
");
}
[WorkItem(12378, "https://github.com/dotnet/roslyn/issues/12378")]
[WorkItem(13971, "https://github.com/dotnet/roslyn/issues/13971")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void PatternSwitchSequencePoints()
{
string source =
@"class Program
{
static void M(object o)
{
switch (o)
{
case 1 when o == null:
case 4:
case 2 when o == null:
break;
case 1 when o != null:
case 5:
case 3 when o != null:
break;
default:
break;
case 1:
break;
}
switch (o)
{
case 1:
break;
default:
break;
}
switch (o)
{
default:
break;
}
}
}";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
CompileAndVerify(c).VerifyIL(qualifiedMethodName: "Program.M", sequencePoints: "Program.M", source: source,
expectedIL: @"{
// Code size 123 (0x7b)
.maxstack 2
.locals init (object V_0,
int V_1,
object V_2,
object V_3,
int V_4,
object V_5,
object V_6,
object V_7)
// sequence point: {
IL_0000: nop
// sequence point: switch (o)
IL_0001: ldarg.0
IL_0002: stloc.2
// sequence point:
IL_0003: ldloc.2
IL_0004: stloc.0
// sequence point:
IL_0005: ldloc.0
IL_0006: isinst ""int""
IL_000b: brfalse.s IL_004a
IL_000d: ldloc.0
IL_000e: unbox.any ""int""
IL_0013: stloc.1
// sequence point:
IL_0014: ldloc.1
IL_0015: ldc.i4.1
IL_0016: sub
IL_0017: switch (
IL_0032,
IL_0037,
IL_0043,
IL_003c,
IL_0048)
IL_0030: br.s IL_004a
// sequence point: when o == null
IL_0032: ldarg.0
IL_0033: brfalse.s IL_003c
// sequence point:
IL_0035: br.s IL_003e
// sequence point: when o == null
IL_0037: ldarg.0
IL_0038: brfalse.s IL_003c
// sequence point:
IL_003a: br.s IL_004a
// sequence point: break;
IL_003c: br.s IL_004e
// sequence point: when o != null
IL_003e: ldarg.0
IL_003f: brtrue.s IL_0048
// sequence point:
IL_0041: br.s IL_004c
// sequence point: when o != null
IL_0043: ldarg.0
IL_0044: brtrue.s IL_0048
// sequence point:
IL_0046: br.s IL_004a
// sequence point: break;
IL_0048: br.s IL_004e
// sequence point: break;
IL_004a: br.s IL_004e
// sequence point: break;
IL_004c: br.s IL_004e
// sequence point: switch (o)
IL_004e: ldarg.0
IL_004f: stloc.s V_5
// sequence point:
IL_0051: ldloc.s V_5
IL_0053: stloc.3
// sequence point:
IL_0054: ldloc.3
IL_0055: isinst ""int""
IL_005a: brfalse.s IL_006d
IL_005c: ldloc.3
IL_005d: unbox.any ""int""
IL_0062: stloc.s V_4
// sequence point:
IL_0064: ldloc.s V_4
IL_0066: ldc.i4.1
IL_0067: beq.s IL_006b
IL_0069: br.s IL_006d
// sequence point: break;
IL_006b: br.s IL_006f
// sequence point: break;
IL_006d: br.s IL_006f
// sequence point: switch (o)
IL_006f: ldarg.0
IL_0070: stloc.s V_7
// sequence point:
IL_0072: ldloc.s V_7
IL_0074: stloc.s V_6
// sequence point:
IL_0076: br.s IL_0078
// sequence point: break;
IL_0078: br.s IL_007a
// sequence point: }
IL_007a: ret
}");
c.VerifyPdb(
@"
");
}
[WorkItem(14437, "https://github.com/dotnet/roslyn/issues/14437")]
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void LocalFunctionSequencePoints()
{
string source =
@"class Program
{
static int Main(string[] args)
{ // 4
int Local1(string[] a)
=>
a.Length; // 7
int Local2(string[] a)
{ // 9
return a.Length; // 10
} // 11
return Local1(args) + Local2(args); // 12
} // 13
}";
var c = CreateCompilationWithMscorlib40AndSystemCore(source, options: TestOptions.DebugDll);
c.VerifyPdb(
@"
0
");
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
[WorkItem(12564, "https://github.com/dotnet/roslyn/issues/12564")]
public void SwitchInAsyncMethod()
{
var source = @"
using System;
class Program
{
public static async void Test()
{
int i = 0;
switch (i)
{
case 1:
break;
}
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
v.VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"
{
// Code size 89 (0x59)
.maxstack 2
.locals init (int V_0,
int V_1,
System.Exception V_2)
// sequence point:
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.d__0.<>1__state""
IL_0006: stloc.0
.try
{
// sequence point: {
IL_0007: nop
// sequence point: int i = 0;
IL_0008: ldarg.0
IL_0009: ldc.i4.0
IL_000a: stfld ""int Program.d__0.5__1""
// sequence point: switch (i)
IL_000f: ldarg.0
IL_0010: ldarg.0
IL_0011: ldfld ""int Program.d__0.5__1""
IL_0016: stloc.1
// sequence point:
IL_0017: ldloc.1
IL_0018: stfld ""int Program.d__0.<>s__2""
// sequence point:
IL_001d: ldarg.0
IL_001e: ldfld ""int Program.d__0.<>s__2""
IL_0023: ldc.i4.1
IL_0024: beq.s IL_0028
IL_0026: br.s IL_002a
// sequence point: break;
IL_0028: br.s IL_002a
IL_002a: leave.s IL_0044
}
catch System.Exception
{
// async: catch handler, sequence point:
IL_002c: stloc.2
IL_002d: ldarg.0
IL_002e: ldc.i4.s -2
IL_0030: stfld ""int Program.d__0.<>1__state""
IL_0035: ldarg.0
IL_0036: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.d__0.<>t__builder""
IL_003b: ldloc.2
IL_003c: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetException(System.Exception)""
IL_0041: nop
IL_0042: leave.s IL_0058
}
// sequence point: }
IL_0044: ldarg.0
IL_0045: ldc.i4.s -2
IL_0047: stfld ""int Program.d__0.<>1__state""
// sequence point:
IL_004c: ldarg.0
IL_004d: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.d__0.<>t__builder""
IL_0052: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult()""
IL_0057: nop
IL_0058: ret
}", sequencePoints: "Program+d__0.MoveNext", source: source);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
[WorkItem(12564, "https://github.com/dotnet/roslyn/issues/12564")]
public void WhileInAsyncMethod()
{
var source = @"
using System;
class Program
{
public static async void Test()
{
int i = 0;
while (i == 1)
Console.WriteLine();
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
v.VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"
{
// Code size 83 (0x53)
.maxstack 2
.locals init (int V_0,
bool V_1,
System.Exception V_2)
// sequence point:
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.d__0.<>1__state""
IL_0006: stloc.0
.try
{
// sequence point: {
IL_0007: nop
// sequence point: int i = 0;
IL_0008: ldarg.0
IL_0009: ldc.i4.0
IL_000a: stfld ""int Program.d__0.5__1""
// sequence point:
IL_000f: br.s IL_0017
// sequence point: Console.WriteLine();
IL_0011: call ""void System.Console.WriteLine()""
IL_0016: nop
// sequence point: while (i == 1)
IL_0017: ldarg.0
IL_0018: ldfld ""int Program.d__0.5__1""
IL_001d: ldc.i4.1
IL_001e: ceq
IL_0020: stloc.1
// sequence point:
IL_0021: ldloc.1
IL_0022: brtrue.s IL_0011
IL_0024: leave.s IL_003e
}
catch System.Exception
{
// async: catch handler, sequence point:
IL_0026: stloc.2
IL_0027: ldarg.0
IL_0028: ldc.i4.s -2
IL_002a: stfld ""int Program.d__0.<>1__state""
IL_002f: ldarg.0
IL_0030: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.d__0.<>t__builder""
IL_0035: ldloc.2
IL_0036: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetException(System.Exception)""
IL_003b: nop
IL_003c: leave.s IL_0052
}
// sequence point: }
IL_003e: ldarg.0
IL_003f: ldc.i4.s -2
IL_0041: stfld ""int Program.d__0.<>1__state""
// sequence point:
IL_0046: ldarg.0
IL_0047: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.d__0.<>t__builder""
IL_004c: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult()""
IL_0051: nop
IL_0052: ret
}
", sequencePoints: "Program+d__0.MoveNext", source: source);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
[WorkItem(12564, "https://github.com/dotnet/roslyn/issues/12564")]
public void ForInAsyncMethod()
{
var source = @"
using System;
class Program
{
public static async void Test()
{
for (int i = 0; i > 1; i--)
Console.WriteLine();
}
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
v.VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"
{
// Code size 99 (0x63)
.maxstack 3
.locals init (int V_0,
int V_1,
bool V_2,
System.Exception V_3)
// sequence point:
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.d__0.<>1__state""
IL_0006: stloc.0
.try
{
// sequence point: {
IL_0007: nop
// sequence point: int i = 0
IL_0008: ldarg.0
IL_0009: ldc.i4.0
IL_000a: stfld ""int Program.d__0.5__1""
// sequence point:
IL_000f: br.s IL_0027
// sequence point: Console.WriteLine();
IL_0011: call ""void System.Console.WriteLine()""
IL_0016: nop
// sequence point: i--
IL_0017: ldarg.0
IL_0018: ldfld ""int Program.d__0.5__1""
IL_001d: stloc.1
IL_001e: ldarg.0
IL_001f: ldloc.1
IL_0020: ldc.i4.1
IL_0021: sub
IL_0022: stfld ""int Program.d__0.5__1""
// sequence point: i > 1
IL_0027: ldarg.0
IL_0028: ldfld ""int Program.d__0.5__1""
IL_002d: ldc.i4.1
IL_002e: cgt
IL_0030: stloc.2
// sequence point:
IL_0031: ldloc.2
IL_0032: brtrue.s IL_0011
IL_0034: leave.s IL_004e
}
catch System.Exception
{
// async: catch handler, sequence point:
IL_0036: stloc.3
IL_0037: ldarg.0
IL_0038: ldc.i4.s -2
IL_003a: stfld ""int Program.d__0.<>1__state""
IL_003f: ldarg.0
IL_0040: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.d__0.<>t__builder""
IL_0045: ldloc.3
IL_0046: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetException(System.Exception)""
IL_004b: nop
IL_004c: leave.s IL_0062
}
// sequence point: }
IL_004e: ldarg.0
IL_004f: ldc.i4.s -2
IL_0051: stfld ""int Program.d__0.<>1__state""
// sequence point:
IL_0056: ldarg.0
IL_0057: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.d__0.<>t__builder""
IL_005c: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult()""
IL_0061: nop
IL_0062: ret
}
", sequencePoints: "Program+d__0.MoveNext", source: source);
}
[ConditionalFact(typeof(WindowsOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
[WorkItem(12564, "https://github.com/dotnet/roslyn/issues/12564")]
public void ForWithInnerLocalsInAsyncMethod()
{
var source = @"
using System;
class Program
{
public static async void Test()
{
for (int i = M(out var x); i > 1; i--)
Console.WriteLine();
}
public static int M(out int x) { x = 0; return 0; }
}
";
var v = CompileAndVerify(source, options: TestOptions.DebugDll);
v.VerifyIL("Program.d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"
{
// Code size 109 (0x6d)
.maxstack 3
.locals init (int V_0,
int V_1,
bool V_2,
System.Exception V_3)
// sequence point:
IL_0000: ldarg.0
IL_0001: ldfld ""int Program.d__0.<>1__state""
IL_0006: stloc.0
.try
{
// sequence point: {
IL_0007: nop
// sequence point: int i = M(out var x)
IL_0008: ldarg.0
IL_0009: ldarg.0
IL_000a: ldflda ""int Program.d__0.5__2""
IL_000f: call ""int Program.M(out int)""
IL_0014: stfld ""int Program.d__0.5__1""
// sequence point:
IL_0019: br.s IL_0031
// sequence point: Console.WriteLine();
IL_001b: call ""void System.Console.WriteLine()""
IL_0020: nop
// sequence point: i--
IL_0021: ldarg.0
IL_0022: ldfld ""int Program.d__0.5__1""
IL_0027: stloc.1
IL_0028: ldarg.0
IL_0029: ldloc.1
IL_002a: ldc.i4.1
IL_002b: sub
IL_002c: stfld ""int Program.d__0.5__1""
// sequence point: i > 1
IL_0031: ldarg.0
IL_0032: ldfld ""int Program.d__0.5__1""
IL_0037: ldc.i4.1
IL_0038: cgt
IL_003a: stloc.2
// sequence point:
IL_003b: ldloc.2
IL_003c: brtrue.s IL_001b
IL_003e: leave.s IL_0058
}
catch System.Exception
{
// async: catch handler, sequence point:
IL_0040: stloc.3
IL_0041: ldarg.0
IL_0042: ldc.i4.s -2
IL_0044: stfld ""int Program.d__0.<>1__state""
IL_0049: ldarg.0
IL_004a: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.d__0.<>t__builder""
IL_004f: ldloc.3
IL_0050: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetException(System.Exception)""
IL_0055: nop
IL_0056: leave.s IL_006c
}
// sequence point: }
IL_0058: ldarg.0
IL_0059: ldc.i4.s -2
IL_005b: stfld ""int Program.d__0.<>1__state""
// sequence point:
IL_0060: ldarg.0
IL_0061: ldflda ""System.Runtime.CompilerServices.AsyncVoidMethodBuilder Program.d__0.<>t__builder""
IL_0066: call ""void System.Runtime.CompilerServices.AsyncVoidMethodBuilder.SetResult()""
IL_006b: nop
IL_006c: ret
}
", sequencePoints: "Program+d__0.MoveNext", source: source);
}
[ConditionalFact(typeof(WindowsDesktopOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
[WorkItem(23525, "https://github.com/dotnet/roslyn/issues/23525")]
public void InvalidCharacterInPdbPath()
{
using (var outStream = Temp.CreateFile().Open())
{
var compilation = CreateCompilation("");
var result = compilation.Emit(outStream, options: new EmitOptions(pdbFilePath: "test\\?.pdb", debugInformationFormat: DebugInformationFormat.Embedded));
Assert.False(result.Success);
result.Diagnostics.Verify(
// error CS2021: File name 'test\?.pdb' is empty, contains invalid characters, has a drive specification without an absolute path, or is too long
Diagnostic(ErrorCode.FTL_InvalidInputFileName).WithArguments("test\\?.pdb").WithLocation(1, 1));
}
}
}
}