Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Partial method tests from test plan review #44303

Merged
merged 2 commits into from
May 18, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -10321,6 +10321,72 @@ partial class C
Assert.False(comp.HasLocalsInit("C.M"));
}

[Fact]
public void SkipLocalsInitAttributeOnExtendedPartialMethod_01()
{
var source = @"
namespace System.Runtime.CompilerServices
{
class SkipLocalsInitAttribute : System.Attribute
{
}
}
partial class C
{
public partial int M()
{
int x = 1;
x = x + x + x;
return x;
}
}
partial class C
{
[System.Runtime.CompilerServices.SkipLocalsInitAttribute]
public partial int M();
}
";

var comp = CompileAndVerify(source, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularWithExtendedPartialMethods, verify: Verification.Fails);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

verify: Verification.Fails [](start = 148, length = 26)

Why does verification fail?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe the verifier is unhappy that locals are not initialized. This is similar to other SkipLocalsInit tests.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we skipping init? If so, why is HasLocalsInit("C.M") returning false?


In reply to: 426860257 [](ancestors = 426860257)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes. HasLocalsInit is returning false because we are skipping locals init. Normally it returns true in most cases, except when the method has no locals or when the SkipLocalsInitAttribute has been applied.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TestOptions.UnsafeReleaseDll [](start = 57, length = 28)

Minor point: Is this needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsafe is required to use SkipLocalsInit


Assert.False(comp.HasLocalsInit("C.M"));
}

[Fact]
public void SkipLocalsInitAttributeOnExtendedPartialMethod_02()
{
var source = @"
namespace System.Runtime.CompilerServices
{
class SkipLocalsInitAttribute : System.Attribute
{
}
}
partial class C
{
[System.Runtime.CompilerServices.SkipLocalsInitAttribute]
public partial int M()
{
int x = 1;
x = x + x + x;
return x;
}
}
partial class C
{
public partial int M();
}
";

var comp = CompileAndVerify(source, options: TestOptions.UnsafeReleaseDll, parseOptions: TestOptions.RegularWithExtendedPartialMethods, verify: Verification.Fails);

Assert.False(comp.HasLocalsInit("C.M"));
}

[Fact]
public unsafe void StackallocWithSkipLocalsInit()
{
Expand Down
262 changes: 262 additions & 0 deletions src/Compilers/CSharp/Test/Emit/CodeGen/CodeGenAsyncIteratorTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3126,6 +3126,268 @@ .locals init (int V_0,
}", sequencePoints: "C+<M>d__0.MoveNext", source: source);
}

[ConditionalTheory(typeof(WindowsDesktopOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
[InlineData("[EnumeratorCancellation] ", "")]
[InlineData("", "[EnumeratorCancellation] ")]
public void AsyncIteratorWithAwaitCompletedAndYield_WithEnumeratorCancellation_ExtendedPartialMethod(string definitionAttributes, string implementationAttributes)
{
string source = @"
using System.Runtime.CompilerServices;
using System.Threading;
partial class C
{
public static partial System.Collections.Generic.IAsyncEnumerable<int> M(" + definitionAttributes + @"CancellationToken token);
public static async partial System.Collections.Generic.IAsyncEnumerable<int> M(" + implementationAttributes + @"CancellationToken token)
{
_ = token;
await System.Threading.Tasks.Task.CompletedTask;
yield return 3;
}
}";
var comp = CreateCompilationWithAsyncIterator(new[] { source, EnumeratorCancellationAttributeType }, options: TestOptions.ReleaseDll, parseOptions: TestOptions.RegularWithExtendedPartialMethods);
comp.VerifyDiagnostics();
var verifier = CompileAndVerify(comp);

var expectedFields = new[] {
"FieldDefinition:Int32 <>1__state",
"FieldDefinition:System.Runtime.CompilerServices.AsyncIteratorMethodBuilder <>t__builder",
"FieldDefinition:System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore`1{Boolean} <>v__promiseOfValueOrEnd",
"FieldDefinition:Int32 <>2__current",
"FieldDefinition:Boolean <>w__disposeMode",
"FieldDefinition:System.Threading.CancellationTokenSource <>x__combinedTokens",
"FieldDefinition:Int32 <>l__initialThreadId",
"FieldDefinition:System.Threading.CancellationToken token",
"FieldDefinition:System.Threading.CancellationToken <>3__token",
"FieldDefinition:System.Runtime.CompilerServices.TaskAwaiter <>u__1"
};
VerifyStateMachineFields(comp, "<M>d__0", expectedFields);

// we generate initialization logic for the token parameter
verifier.VerifyIL("C.<M>d__0.System.Collections.Generic.IAsyncEnumerable<int>.GetAsyncEnumerator(System.Threading.CancellationToken)", @"
{
// Code size 176 (0xb0)
.maxstack 3
.locals init (C.<M>d__0 V_0,
System.Threading.CancellationToken V_1)
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<M>d__0.<>1__state""
IL_0006: ldc.i4.s -2
IL_0008: bne.un.s IL_0035
IL_000a: ldarg.0
IL_000b: ldfld ""int C.<M>d__0.<>l__initialThreadId""
IL_0010: call ""int System.Environment.CurrentManagedThreadId.get""
IL_0015: bne.un.s IL_0035
IL_0017: ldarg.0
IL_0018: ldc.i4.s -3
IL_001a: stfld ""int C.<M>d__0.<>1__state""
IL_001f: ldarg.0
IL_0020: call ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Create()""
IL_0025: stfld ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.<M>d__0.<>t__builder""
IL_002a: ldarg.0
IL_002b: ldc.i4.0
IL_002c: stfld ""bool C.<M>d__0.<>w__disposeMode""
IL_0031: ldarg.0
IL_0032: stloc.0
IL_0033: br.s IL_003d
IL_0035: ldc.i4.s -3
IL_0037: newobj ""C.<M>d__0..ctor(int)""
IL_003c: stloc.0
IL_003d: ldarg.0
IL_003e: ldflda ""System.Threading.CancellationToken C.<M>d__0.<>3__token""
IL_0043: ldloca.s V_1
IL_0045: initobj ""System.Threading.CancellationToken""
IL_004b: ldloc.1
IL_004c: call ""bool System.Threading.CancellationToken.Equals(System.Threading.CancellationToken)""
IL_0051: brfalse.s IL_005c
IL_0053: ldloc.0
IL_0054: ldarg.1
IL_0055: stfld ""System.Threading.CancellationToken C.<M>d__0.token""
IL_005a: br.s IL_00ae
IL_005c: ldarga.s V_1
IL_005e: ldarg.0
IL_005f: ldfld ""System.Threading.CancellationToken C.<M>d__0.<>3__token""
IL_0064: call ""bool System.Threading.CancellationToken.Equals(System.Threading.CancellationToken)""
IL_0069: brtrue.s IL_007d
IL_006b: ldarga.s V_1
IL_006d: ldloca.s V_1
IL_006f: initobj ""System.Threading.CancellationToken""
IL_0075: ldloc.1
IL_0076: call ""bool System.Threading.CancellationToken.Equals(System.Threading.CancellationToken)""
IL_007b: brfalse.s IL_008b
IL_007d: ldloc.0
IL_007e: ldarg.0
IL_007f: ldfld ""System.Threading.CancellationToken C.<M>d__0.<>3__token""
IL_0084: stfld ""System.Threading.CancellationToken C.<M>d__0.token""
IL_0089: br.s IL_00ae
IL_008b: ldarg.0
IL_008c: ldarg.0
IL_008d: ldfld ""System.Threading.CancellationToken C.<M>d__0.<>3__token""
IL_0092: ldarg.1
IL_0093: call ""System.Threading.CancellationTokenSource System.Threading.CancellationTokenSource.CreateLinkedTokenSource(System.Threading.CancellationToken, System.Threading.CancellationToken)""
IL_0098: stfld ""System.Threading.CancellationTokenSource C.<M>d__0.<>x__combinedTokens""
IL_009d: ldloc.0
IL_009e: ldarg.0
IL_009f: ldfld ""System.Threading.CancellationTokenSource C.<M>d__0.<>x__combinedTokens""
IL_00a4: callvirt ""System.Threading.CancellationToken System.Threading.CancellationTokenSource.Token.get""
IL_00a9: stfld ""System.Threading.CancellationToken C.<M>d__0.token""
IL_00ae: ldloc.0
IL_00af: ret
}");

// we generate disposal logic for the combinedTokens field
verifier.VerifyIL("C.<M>d__0.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @"
{
// Code size 329 (0x149)
.maxstack 3
.locals init (int V_0,
System.Runtime.CompilerServices.TaskAwaiter V_1,
C.<M>d__0 V_2,
System.Exception V_3)
// sequence point: <hidden>
IL_0000: ldarg.0
IL_0001: ldfld ""int C.<M>d__0.<>1__state""
IL_0006: stloc.0
.try
{
// sequence point: <hidden>
IL_0007: ldloc.0
IL_0008: ldc.i4.s -4
IL_000a: sub
IL_000b: switch (
IL_00b4,
IL_0024,
IL_0024,
IL_0024,
IL_007b)
IL_0024: ldarg.0
IL_0025: ldfld ""bool C.<M>d__0.<>w__disposeMode""
IL_002a: brfalse.s IL_0031
IL_002c: leave IL_0102
IL_0031: ldarg.0
IL_0032: ldc.i4.m1
IL_0033: dup
IL_0034: stloc.0
IL_0035: stfld ""int C.<M>d__0.<>1__state""
// sequence point: _ = token;
IL_003a: ldarg.0
IL_003b: ldfld ""System.Threading.CancellationToken C.<M>d__0.token""
IL_0040: pop
// sequence point: await System.Threading.Tasks.Task.CompletedTask;
IL_0041: call ""System.Threading.Tasks.Task System.Threading.Tasks.Task.CompletedTask.get""
IL_0046: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()""
IL_004b: stloc.1
// sequence point: <hidden>
IL_004c: ldloca.s V_1
IL_004e: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get""
IL_0053: brtrue.s IL_0097
IL_0055: ldarg.0
IL_0056: ldc.i4.0
IL_0057: dup
IL_0058: stloc.0
IL_0059: stfld ""int C.<M>d__0.<>1__state""
// async: yield
IL_005e: ldarg.0
IL_005f: ldloc.1
IL_0060: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.<M>d__0.<>u__1""
IL_0065: ldarg.0
IL_0066: stloc.2
IL_0067: ldarg.0
IL_0068: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.<M>d__0.<>t__builder""
IL_006d: ldloca.s V_1
IL_006f: ldloca.s V_2
IL_0071: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.AwaitUnsafeOnCompleted<System.Runtime.CompilerServices.TaskAwaiter, C.<M>d__0>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.<M>d__0)""
IL_0076: leave IL_0148
// async: resume
IL_007b: ldarg.0
IL_007c: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.<M>d__0.<>u__1""
IL_0081: stloc.1
IL_0082: ldarg.0
IL_0083: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.<M>d__0.<>u__1""
IL_0088: initobj ""System.Runtime.CompilerServices.TaskAwaiter""
IL_008e: ldarg.0
IL_008f: ldc.i4.m1
IL_0090: dup
IL_0091: stloc.0
IL_0092: stfld ""int C.<M>d__0.<>1__state""
IL_0097: ldloca.s V_1
IL_0099: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()""
// sequence point: yield return 3;
IL_009e: ldarg.0
IL_009f: ldc.i4.3
IL_00a0: stfld ""int C.<M>d__0.<>2__current""
IL_00a5: ldarg.0
IL_00a6: ldc.i4.s -4
IL_00a8: dup
IL_00a9: stloc.0
IL_00aa: stfld ""int C.<M>d__0.<>1__state""
IL_00af: leave IL_013c
// sequence point: <hidden>
IL_00b4: ldarg.0
IL_00b5: ldc.i4.m1
IL_00b6: dup
IL_00b7: stloc.0
IL_00b8: stfld ""int C.<M>d__0.<>1__state""
IL_00bd: ldarg.0
IL_00be: ldfld ""bool C.<M>d__0.<>w__disposeMode""
IL_00c3: pop
// sequence point: <hidden>
IL_00c4: leave.s IL_0102
}
catch System.Exception
{
// sequence point: <hidden>
IL_00c6: stloc.3
IL_00c7: ldarg.0
IL_00c8: ldc.i4.s -2
IL_00ca: stfld ""int C.<M>d__0.<>1__state""
IL_00cf: ldarg.0
IL_00d0: ldfld ""System.Threading.CancellationTokenSource C.<M>d__0.<>x__combinedTokens""
IL_00d5: brfalse.s IL_00e9
IL_00d7: ldarg.0
IL_00d8: ldfld ""System.Threading.CancellationTokenSource C.<M>d__0.<>x__combinedTokens""
IL_00dd: callvirt ""void System.Threading.CancellationTokenSource.Dispose()""
IL_00e2: ldarg.0
IL_00e3: ldnull
IL_00e4: stfld ""System.Threading.CancellationTokenSource C.<M>d__0.<>x__combinedTokens""
IL_00e9: ldarg.0
IL_00ea: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore<bool> C.<M>d__0.<>v__promiseOfValueOrEnd""
IL_00ef: ldloc.3
IL_00f0: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore<bool>.SetException(System.Exception)""
IL_00f5: ldarg.0
IL_00f6: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.<M>d__0.<>t__builder""
IL_00fb: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()""
IL_0100: leave.s IL_0148
}
// sequence point: }
IL_0102: ldarg.0
IL_0103: ldc.i4.s -2
IL_0105: stfld ""int C.<M>d__0.<>1__state""
// sequence point: <hidden>
IL_010a: ldarg.0
IL_010b: ldfld ""System.Threading.CancellationTokenSource C.<M>d__0.<>x__combinedTokens""
IL_0110: brfalse.s IL_0124
IL_0112: ldarg.0
IL_0113: ldfld ""System.Threading.CancellationTokenSource C.<M>d__0.<>x__combinedTokens""
IL_0118: callvirt ""void System.Threading.CancellationTokenSource.Dispose()""
IL_011d: ldarg.0
IL_011e: ldnull
IL_011f: stfld ""System.Threading.CancellationTokenSource C.<M>d__0.<>x__combinedTokens""
IL_0124: ldarg.0
IL_0125: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore<bool> C.<M>d__0.<>v__promiseOfValueOrEnd""
IL_012a: ldc.i4.0
IL_012b: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore<bool>.SetResult(bool)""
IL_0130: ldarg.0
IL_0131: ldflda ""System.Runtime.CompilerServices.AsyncIteratorMethodBuilder C.<M>d__0.<>t__builder""
IL_0136: call ""void System.Runtime.CompilerServices.AsyncIteratorMethodBuilder.Complete()""
IL_013b: ret
IL_013c: ldarg.0
IL_013d: ldflda ""System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore<bool> C.<M>d__0.<>v__promiseOfValueOrEnd""
IL_0142: ldc.i4.1
IL_0143: call ""void System.Threading.Tasks.Sources.ManualResetValueTaskSourceCore<bool>.SetResult(bool)""
IL_0148: ret
}", sequencePoints: "C+<M>d__0.MoveNext", source: source);
}

[ConditionalFact(typeof(WindowsDesktopOnly), Reason = ConditionalSkipReason.NativePdbRequiresDesktop)]
public void AsyncIteratorWithAwaitCompletedAndYield_WithEnumeratorCancellation_LocalFunction()
{
Expand Down
Loading