提交 52a6eb32 编写于 作者: A Alireza Habibi 提交者: Julien Couvreur

Add suggested stackalloc initializer tests (#25656)

上级 0e73b2f1
......@@ -9,6 +9,215 @@ namespace Microsoft.CodeAnalysis.CSharp.UnitTests
[CompilerTrait(CompilerFeature.StackAllocInitializer)]
public class CodeGenStackAllocInitializerTests : CompilingTestBase
{
[Fact]
public void TestUnmanaged_Pointer()
{
var text = @"
using System;
unsafe class Test
{
static void Print<T>(T* p) where T : unmanaged
{
for (int i = 0; i < 3; i++)
Console.Write(p[i]);
}
static void M<T>(T arg) where T : unmanaged
{
var obj1 = stackalloc T[3] { arg, arg, arg };
Print<T>(obj1);
var obj2 = stackalloc T[ ] { arg, arg, arg };
Print<T>(obj2);
var obj3 = stackalloc [ ] { arg, arg, arg };
Print<T>(obj3);
}
public static void Main()
{
M(42);
}
}";
CompileAndVerify(text,
parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3),
options: TestOptions.UnsafeReleaseExe,
expectedOutput: "424242424242424242",
verify: Verification.Fails).VerifyIL("Test.M<T>(T)",
@"{
// Code size 163 (0xa3)
.maxstack 4
IL_0000: ldc.i4.3
IL_0001: conv.u
IL_0002: sizeof ""T""
IL_0008: mul.ovf.un
IL_0009: localloc
IL_000b: dup
IL_000c: ldarg.0
IL_000d: stobj ""T""
IL_0012: dup
IL_0013: sizeof ""T""
IL_0019: add
IL_001a: ldarg.0
IL_001b: stobj ""T""
IL_0020: dup
IL_0021: ldc.i4.2
IL_0022: conv.i
IL_0023: sizeof ""T""
IL_0029: mul
IL_002a: add
IL_002b: ldarg.0
IL_002c: stobj ""T""
IL_0031: call ""void Test.Print<T>(T*)""
IL_0036: ldc.i4.3
IL_0037: conv.u
IL_0038: sizeof ""T""
IL_003e: mul.ovf.un
IL_003f: localloc
IL_0041: dup
IL_0042: ldarg.0
IL_0043: stobj ""T""
IL_0048: dup
IL_0049: sizeof ""T""
IL_004f: add
IL_0050: ldarg.0
IL_0051: stobj ""T""
IL_0056: dup
IL_0057: ldc.i4.2
IL_0058: conv.i
IL_0059: sizeof ""T""
IL_005f: mul
IL_0060: add
IL_0061: ldarg.0
IL_0062: stobj ""T""
IL_0067: call ""void Test.Print<T>(T*)""
IL_006c: ldc.i4.3
IL_006d: conv.u
IL_006e: sizeof ""T""
IL_0074: mul.ovf.un
IL_0075: localloc
IL_0077: dup
IL_0078: ldarg.0
IL_0079: stobj ""T""
IL_007e: dup
IL_007f: sizeof ""T""
IL_0085: add
IL_0086: ldarg.0
IL_0087: stobj ""T""
IL_008c: dup
IL_008d: ldc.i4.2
IL_008e: conv.i
IL_008f: sizeof ""T""
IL_0095: mul
IL_0096: add
IL_0097: ldarg.0
IL_0098: stobj ""T""
IL_009d: call ""void Test.Print<T>(T*)""
IL_00a2: ret
}");
}
[Fact]
public void TestUnmanaged_Span()
{
var comp = CreateCompilationWithMscorlibAndSpan(@"
using System;
class Test
{
public void M<T>(T arg) where T : unmanaged
{
Span<T> obj1 = stackalloc T[3] { arg, arg, arg };
Span<T> obj2 = stackalloc T[ ] { arg, arg, arg };
Span<T> obj3 = stackalloc [ ] { arg, arg, arg };
}
}
", options: TestOptions.ReleaseDll, parseOptions: TestOptions.Regular.WithLanguageVersion(LanguageVersion.CSharp7_3));
CompileAndVerify(comp, verify: Verification.Fails).VerifyIL("Test.M<T>(T)",
@"{
// Code size 175 (0xaf)
.maxstack 4
.locals init (int V_0)
IL_0000: ldc.i4.3
IL_0001: stloc.0
IL_0002: ldloc.0
IL_0003: conv.u
IL_0004: sizeof ""T""
IL_000a: mul.ovf.un
IL_000b: localloc
IL_000d: dup
IL_000e: ldarg.1
IL_000f: stobj ""T""
IL_0014: dup
IL_0015: sizeof ""T""
IL_001b: add
IL_001c: ldarg.1
IL_001d: stobj ""T""
IL_0022: dup
IL_0023: ldc.i4.2
IL_0024: conv.i
IL_0025: sizeof ""T""
IL_002b: mul
IL_002c: add
IL_002d: ldarg.1
IL_002e: stobj ""T""
IL_0033: ldloc.0
IL_0034: newobj ""System.Span<T>..ctor(void*, int)""
IL_0039: pop
IL_003a: ldc.i4.3
IL_003b: stloc.0
IL_003c: ldloc.0
IL_003d: conv.u
IL_003e: sizeof ""T""
IL_0044: mul.ovf.un
IL_0045: localloc
IL_0047: dup
IL_0048: ldarg.1
IL_0049: stobj ""T""
IL_004e: dup
IL_004f: sizeof ""T""
IL_0055: add
IL_0056: ldarg.1
IL_0057: stobj ""T""
IL_005c: dup
IL_005d: ldc.i4.2
IL_005e: conv.i
IL_005f: sizeof ""T""
IL_0065: mul
IL_0066: add
IL_0067: ldarg.1
IL_0068: stobj ""T""
IL_006d: ldloc.0
IL_006e: newobj ""System.Span<T>..ctor(void*, int)""
IL_0073: pop
IL_0074: ldc.i4.3
IL_0075: stloc.0
IL_0076: ldloc.0
IL_0077: conv.u
IL_0078: sizeof ""T""
IL_007e: mul.ovf.un
IL_007f: localloc
IL_0081: dup
IL_0082: ldarg.1
IL_0083: stobj ""T""
IL_0088: dup
IL_0089: sizeof ""T""
IL_008f: add
IL_0090: ldarg.1
IL_0091: stobj ""T""
IL_0096: dup
IL_0097: ldc.i4.2
IL_0098: conv.i
IL_0099: sizeof ""T""
IL_009f: mul
IL_00a0: add
IL_00a1: ldarg.1
IL_00a2: stobj ""T""
IL_00a7: ldloc.0
IL_00a8: newobj ""System.Span<T>..ctor(void*, int)""
IL_00ad: pop
IL_00ae: ret
}");
}
[Fact]
public void TestLambdaCapture()
{
......
......@@ -1151,17 +1151,19 @@ static void Main()
}
[Fact]
public void TestStackAllocArrayInitializer()
public void TestImplicitStackAllocArrayInitializer()
{
var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class C {
static void Main()
{
int z = 1;
int y = 1;
var x = stackalloc[] {
/*<bind>*/
y
/*</bind>*/
, z++
};
}
}
......@@ -1171,9 +1173,37 @@ static void Main()
Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
Assert.Equal(null, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
Assert.Equal(null, GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
Assert.Equal("z", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
Assert.Equal(null, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
Assert.Equal("y, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
Assert.Equal("z, y, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
}
[Fact]
public void TestStackAllocArrayInitializer()
{
var dataFlowAnalysisResults = CompileAndAnalyzeDataFlowExpression(@"
class C {
static void Main()
{
int z = 1;
int y = 1;
var x = stackalloc int[] {
/*<bind>*/
y
/*</bind>*/
, z++
};
}
}
");
Assert.Equal(null, GetSymbolNamesJoined(dataFlowAnalysisResults.VariablesDeclared));
Assert.Equal(null, GetSymbolNamesJoined(dataFlowAnalysisResults.AlwaysAssigned));
Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsIn));
Assert.Equal(null, GetSymbolNamesJoined(dataFlowAnalysisResults.DataFlowsOut));
Assert.Equal("y", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadInside));
Assert.Equal("z", GetSymbolNamesJoined(dataFlowAnalysisResults.ReadOutside));
Assert.Equal(null, GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenInside));
Assert.Equal("z, y, x", GetSymbolNamesJoined(dataFlowAnalysisResults.WrittenOutside));
}
[WorkItem(539286, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/539286")]
......
......@@ -273,6 +273,54 @@ void Method1(S s)
// var obj2 = stackalloc[] { new {} };
Diagnostic(ErrorCode.ERR_ManagedAddr, "stackalloc[] { new {} }").WithArguments("<empty anonymous type>").WithLocation(8, 20)
);
var tree = comp.SyntaxTrees.Single();
var model = comp.GetSemanticModel(tree);
var expressions = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ImplicitStackAllocArrayCreationExpressionSyntax>().ToArray();
Assert.Equal(3, expressions.Length);
var @stackalloc = expressions[0];
var stackallocInfo = model.GetSemanticInfoSummary(@stackalloc);
Assert.Null(stackallocInfo.Symbol);
Assert.Equal("System.String*", stackallocInfo.Type.ToTestDisplayString());
Assert.Equal("System.String*", stackallocInfo.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, stackallocInfo.ImplicitConversion);
var element0Info = model.GetSemanticInfoSummary(@stackalloc.Initializer.Expressions[0]);
Assert.Null(element0Info.Symbol);
Assert.Equal("System.String", element0Info.Type.ToTestDisplayString());
Assert.Equal("System.String", element0Info.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, element0Info.ImplicitConversion);
@stackalloc = expressions[1];
stackallocInfo = model.GetSemanticInfoSummary(@stackalloc);
Assert.Null(stackallocInfo.Symbol);
Assert.Equal("<empty anonymous type>*", stackallocInfo.Type.ToTestDisplayString());
Assert.Equal("<empty anonymous type>*", stackallocInfo.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, stackallocInfo.ImplicitConversion);
element0Info = model.GetSemanticInfoSummary(@stackalloc.Initializer.Expressions[0]);
Assert.Equal("<empty anonymous type>..ctor()", element0Info.Symbol.ToTestDisplayString());
Assert.Equal("<empty anonymous type>", element0Info.Type.ToTestDisplayString());
Assert.Equal("<empty anonymous type>", element0Info.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, element0Info.ImplicitConversion);
@stackalloc = expressions[2];
stackallocInfo = model.GetSemanticInfoSummary(@stackalloc);
Assert.Null(stackallocInfo.Symbol);
Assert.Equal("Test.S*", stackallocInfo.Type.ToTestDisplayString());
Assert.Equal("Test.S*", stackallocInfo.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, stackallocInfo.ImplicitConversion);
element0Info = model.GetSemanticInfoSummary(@stackalloc.Initializer.Expressions[0]);
Assert.Equal("Test.S s", element0Info.Symbol.ToTestDisplayString());
Assert.Equal("Test.S", element0Info.Type.ToTestDisplayString());
Assert.Equal("Test.S", element0Info.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, element0Info.ImplicitConversion);
}
[Fact]
......@@ -301,6 +349,54 @@ void Method1(S s, bool c)
// var obj3 = c ? default : stackalloc[] { s };
Diagnostic(ErrorCode.ERR_BadTypeArgument, "stackalloc[] { s }").WithArguments("Test.S").WithLocation(9, 34)
);
var tree = comp.SyntaxTrees.Single();
var model = comp.GetSemanticModel(tree);
var expressions = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ImplicitStackAllocArrayCreationExpressionSyntax>().ToArray();
Assert.Equal(3, expressions.Length);
var @stackalloc = expressions[0];
var stackallocInfo = model.GetSemanticInfoSummary(@stackalloc);
Assert.Null(stackallocInfo.Symbol);
Assert.Equal("System.Span<System.String>", stackallocInfo.Type.ToTestDisplayString());
Assert.Equal("System.Span<System.String>", stackallocInfo.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, stackallocInfo.ImplicitConversion);
var element0Info = model.GetSemanticInfoSummary(@stackalloc.Initializer.Expressions[0]);
Assert.Null(element0Info.Symbol);
Assert.Equal("System.String", element0Info.Type.ToTestDisplayString());
Assert.Equal("System.String", element0Info.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, element0Info.ImplicitConversion);
@stackalloc = expressions[1];
stackallocInfo = model.GetSemanticInfoSummary(@stackalloc);
Assert.Null(stackallocInfo.Symbol);
Assert.Equal("System.Span<<empty anonymous type>>", stackallocInfo.Type.ToTestDisplayString());
Assert.Equal("System.Span<<empty anonymous type>>", stackallocInfo.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, stackallocInfo.ImplicitConversion);
element0Info = model.GetSemanticInfoSummary(@stackalloc.Initializer.Expressions[0]);
Assert.Equal("<empty anonymous type>..ctor()", element0Info.Symbol.ToTestDisplayString());
Assert.Equal("<empty anonymous type>", element0Info.Type.ToTestDisplayString());
Assert.Equal("<empty anonymous type>", element0Info.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, element0Info.ImplicitConversion);
@stackalloc = expressions[2];
stackallocInfo = model.GetSemanticInfoSummary(@stackalloc);
Assert.Null(stackallocInfo.Symbol);
Assert.Equal("System.Span<Test.S>", stackallocInfo.Type.ToTestDisplayString());
Assert.Equal("System.Span<Test.S>", stackallocInfo.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, stackallocInfo.ImplicitConversion);
element0Info = model.GetSemanticInfoSummary(@stackalloc.Initializer.Expressions[0]);
Assert.Equal("Test.S s", element0Info.Symbol.ToTestDisplayString());
Assert.Equal("Test.S", element0Info.Type.ToTestDisplayString());
Assert.Equal("Test.S", element0Info.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, element0Info.ImplicitConversion);
}
[Fact]
......@@ -381,6 +477,115 @@ public static void Main()
comp.VerifyDiagnostics();
}
[Fact]
public void TestForTernary()
{
var comp = CreateCompilationWithMscorlibAndSpan(@"
class Test
{
static void Method1(bool b)
{
for (var p = b ? stackalloc int[3] { 1, 2, 3 } : default; false;) {}
for (var p = b ? stackalloc int[ ] { 1, 2, 3 } : default; false;) {}
for (var p = b ? stackalloc [ ] { 1, 2, 3 } : default; false;) {}
}
}", TestOptions.ReleaseDll);
comp.VerifyDiagnostics();
}
[Fact]
public void TestLock()
{
var comp = CreateCompilationWithMscorlibAndSpan(@"
class Test
{
static void Method1()
{
lock (stackalloc int[3] { 1, 2, 3 }) {}
lock (stackalloc int[ ] { 1, 2, 3 }) {}
lock (stackalloc [ ] { 1, 2, 3 }) {}
}
}", TestOptions.ReleaseDll);
comp.VerifyDiagnostics(
// (6,15): error CS1525: Invalid expression term 'stackalloc'
// lock (stackalloc int[3] { 1, 2, 3 }) {}
Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(6, 15),
// (6,15): error CS0185: 'stackalloc int[3]' is not a reference type as required by the lock statement
// lock (stackalloc int[3] { 1, 2, 3 }) {}
Diagnostic(ErrorCode.ERR_LockNeedsReference, "stackalloc int[3] { 1, 2, 3 }").WithArguments("stackalloc int[3]").WithLocation(6, 15),
// (7,15): error CS1525: Invalid expression term 'stackalloc'
// lock (stackalloc int[ ] { 1, 2, 3 }) {}
Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(7, 15),
// (7,15): error CS0185: 'stackalloc int[]' is not a reference type as required by the lock statement
// lock (stackalloc int[ ] { 1, 2, 3 }) {}
Diagnostic(ErrorCode.ERR_LockNeedsReference, "stackalloc int[ ] { 1, 2, 3 }").WithArguments("stackalloc int[]").WithLocation(7, 15),
// (8,15): error CS1525: Invalid expression term 'stackalloc'
// lock (stackalloc [ ] { 1, 2, 3 }) {}
Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(8, 15),
// (8,15): error CS0185: 'stackalloc int[]' is not a reference type as required by the lock statement
// lock (stackalloc [ ] { 1, 2, 3 }) {}
Diagnostic(ErrorCode.ERR_LockNeedsReference, "stackalloc [ ] { 1, 2, 3 }").WithArguments("stackalloc int[]").WithLocation(8, 15)
);
}
[Fact]
public void TestSelect()
{
var comp = CreateCompilationWithMscorlibAndSpan(@"
using System.Linq;
class Test
{
static void Method1(int[] array)
{
var q1 = from item in array select stackalloc int[3] { 1, 2, 3 };
var q2 = from item in array select stackalloc int[ ] { 1, 2, 3 };
var q3 = from item in array select stackalloc [ ] { 1, 2, 3 };
}
}", TestOptions.ReleaseDll);
comp.VerifyDiagnostics(
// (7,44): error CS1525: Invalid expression term 'stackalloc'
// var q1 = from item in array select stackalloc int[3] { 1, 2, 3 };
Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(7, 44),
// (8,44): error CS1525: Invalid expression term 'stackalloc'
// var q2 = from item in array select stackalloc int[ ] { 1, 2, 3 };
Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(8, 44),
// (9,44): error CS1525: Invalid expression term 'stackalloc'
// var q3 = from item in array select stackalloc [ ] { 1, 2, 3 };
Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(9, 44)
);
}
[Fact]
public void TestLet()
{
var comp = CreateCompilationWithMscorlibAndSpan(@"
using System.Linq;
class Test
{
static void Method1(int[] array)
{
var q1 = from item in array let v = stackalloc int[3] { 1, 2, 3 } select v;
var q2 = from item in array let v = stackalloc int[ ] { 1, 2, 3 } select v;
var q3 = from item in array let v = stackalloc [ ] { 1, 2, 3 } select v;
}
}", TestOptions.ReleaseDll);
comp.VerifyDiagnostics(
// (7,45): error CS1525: Invalid expression term 'stackalloc'
// var q1 = from item in array let v = stackalloc int[3] { 1, 2, 3 } select v;
Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(7, 45),
// (8,45): error CS1525: Invalid expression term 'stackalloc'
// var q2 = from item in array let v = stackalloc int[ ] { 1, 2, 3 } select v;
Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(8, 45),
// (9,45): error CS1525: Invalid expression term 'stackalloc'
// var q3 = from item in array let v = stackalloc [ ] { 1, 2, 3 } select v;
Diagnostic(ErrorCode.ERR_InvalidExprTerm, "stackalloc").WithArguments("stackalloc").WithLocation(9, 45)
);
}
[Fact]
public void TestAwait_Pointer()
{
......@@ -1965,14 +2170,19 @@ public void Method1()
{
var obj1 = stackalloc double[2] { 1, 1.2 };
Span<double> obj2 = stackalloc double[2] { 1, 1.2 };
_ = stackalloc double[2] { 1, 1.2 };
}
}", TestOptions.UnsafeReleaseDll).VerifyDiagnostics();
}", TestOptions.UnsafeReleaseDll).VerifyDiagnostics(
// (9,13): error CS8353: A result of a stackalloc expression of type 'Span<double>' cannot be used in this context because it may be exposed outside of the containing method
// _ = stackalloc double[2] { 1, 1.2 };
Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc double[2] { 1, 1.2 }").WithArguments("System.Span<double>").WithLocation(9, 13)
);
var tree = comp.SyntaxTrees.Single();
var model = comp.GetSemanticModel(tree);
var expressions = tree.GetCompilationUnitRoot().DescendantNodes().OfType<StackAllocArrayCreationExpressionSyntax>().ToArray();
Assert.Equal(2, expressions.Length);
Assert.Equal(3, expressions.Length);
var @stackalloc = expressions[0];
var stackallocInfo = model.GetSemanticInfoSummary(@stackalloc);
......@@ -2029,6 +2239,34 @@ public void Method1()
Assert.Equal(Conversion.Identity, sizeInfo.ImplicitConversion);
Assert.Null(model.GetDeclaredSymbol(@stackalloc));
@stackalloc = expressions[2];
stackallocInfo = model.GetSemanticInfoSummary(@stackalloc);
Assert.Null(stackallocInfo.Symbol);
Assert.Equal("System.Span<System.Double>", stackallocInfo.Type.ToTestDisplayString());
Assert.Equal("System.Span<System.Double>", stackallocInfo.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, stackallocInfo.ImplicitConversion);
element0Info = model.GetSemanticInfoSummary(@stackalloc.Initializer.Expressions[0]);
Assert.Null(element0Info.Symbol);
Assert.Equal("System.Int32", element0Info.Type.ToTestDisplayString());
Assert.Equal("System.Double", element0Info.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.ImplicitNumeric, element0Info.ImplicitConversion);
element1Info = model.GetSemanticInfoSummary(@stackalloc.Initializer.Expressions[1]);
Assert.Null(element1Info.Symbol);
Assert.Equal("System.Double", element1Info.Type.ToTestDisplayString());
Assert.Equal("System.Double", element1Info.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, element1Info.ImplicitConversion);
sizeInfo = model.GetSemanticInfoSummary(((ArrayTypeSyntax)@stackalloc.Type).RankSpecifiers[0].Sizes[0]);
Assert.Null(sizeInfo.Symbol);
Assert.Equal("System.Int32", sizeInfo.Type.ToTestDisplayString());
Assert.Equal("System.Int32", sizeInfo.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, sizeInfo.ImplicitConversion);
Assert.Null(model.GetDeclaredSymbol(@stackalloc));
}
[Fact]
......@@ -2042,14 +2280,19 @@ public void Method1()
{
var obj1 = stackalloc[] { 1, 1.2 };
Span<double> obj2 = stackalloc[] { 1, 1.2 };
_ = stackalloc[] { 1, 1.2 };
}
}", TestOptions.UnsafeReleaseDll).VerifyDiagnostics();
}", TestOptions.UnsafeReleaseDll).VerifyDiagnostics(
// (9,13): error CS8353: A result of a stackalloc expression of type 'Span<double>' cannot be used in this context because it may be exposed outside of the containing method
// _ = stackalloc[] { 1, 1.2 };
Diagnostic(ErrorCode.ERR_EscapeStackAlloc, "stackalloc[] { 1, 1.2 }").WithArguments("System.Span<double>").WithLocation(9, 13)
);
var tree = comp.SyntaxTrees.Single();
var model = comp.GetSemanticModel(tree);
var expressions = tree.GetCompilationUnitRoot().DescendantNodes().OfType<ImplicitStackAllocArrayCreationExpressionSyntax>().ToArray();
Assert.Equal(2, expressions.Length);
Assert.Equal(3, expressions.Length);
var @stackalloc = expressions[0];
var stackallocInfo = model.GetSemanticInfoSummary(@stackalloc);
......@@ -2094,6 +2337,28 @@ public void Method1()
Assert.Equal(Conversion.Identity, element1Info.ImplicitConversion);
Assert.Null(model.GetDeclaredSymbol(@stackalloc));
@stackalloc = expressions[2];
stackallocInfo = model.GetSemanticInfoSummary(@stackalloc);
Assert.Null(stackallocInfo.Symbol);
Assert.Equal("System.Span<System.Double>", stackallocInfo.Type.ToTestDisplayString());
Assert.Equal("System.Span<System.Double>", stackallocInfo.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, stackallocInfo.ImplicitConversion);
element0Info = model.GetSemanticInfoSummary(@stackalloc.Initializer.Expressions[0]);
Assert.Null(element0Info.Symbol);
Assert.Equal("System.Int32", element0Info.Type.ToTestDisplayString());
Assert.Equal("System.Double", element0Info.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.ImplicitNumeric, element0Info.ImplicitConversion);
element1Info = model.GetSemanticInfoSummary(@stackalloc.Initializer.Expressions[1]);
Assert.Null(element1Info.Symbol);
Assert.Equal("System.Double", element1Info.Type.ToTestDisplayString());
Assert.Equal("System.Double", element1Info.ConvertedType.ToTestDisplayString());
Assert.Equal(Conversion.Identity, element1Info.ImplicitConversion);
Assert.Null(model.GetDeclaredSymbol(@stackalloc));
}
[Fact]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册