提交 284b62fe 编写于 作者: E Evan Hauck

Merge pull request #11341 from khyperia/addDynamicTests

Add more tests for recently-fixed dynamic bugs
......@@ -6,3 +6,7 @@ Each entry should include a short description of the break, followed by either a
1. In some cases, due to a bug in the native compiler, programs with pointers to structs with one or more
type parameters compiled without error. All such programs should now produce errors in Roslyn. See
[#5712](https://github.com/dotnet/roslyn/issues/5712) for examples and details.
2. When calling a method group with only instance methods in a static context with dynamic arguments, the
native compiler generated no warnings/errors and emitted code that would always throw when executed.
Roslyn produces an error in this situation. See [#11341](https://github.com/dotnet/roslyn/pull/11341) for when this decision was made,
[#11256](https://github.com/dotnet/roslyn/pull/11256) for when it was discovered, and [#10463](https://github.com/dotnet/roslyn/issues/10463) for the original issue that led to this.
......@@ -14902,5 +14902,407 @@ .maxstack 10
IL_0072: ret
}");
}
[WorkItem(10463, "https://github.com/dotnet/roslyn/issues/10463")]
[Fact]
public void FieldInitializerDynamicParameter()
{
string source = @"
using System;
class M
{
// inner call is dynamic parameter, static argument
// outer call is dynamic parameter, dynamic argument
object a = Test(Test(2));
static dynamic Test(dynamic obj) => obj;
static void Main()
{
Console.Write(new M().a);
}
}
";
var compilation = CompileAndVerify(source, new[] { SystemCoreRef, CSharpRef }, expectedOutput: "2");
compilation.VerifyIL("M..ctor",
@"{
// Code size 120 (0x78)
.maxstack 10
IL_0000: ldarg.0
IL_0001: ldsfld ""System.Runtime.CompilerServices.CallSite<System.Func<System.Runtime.CompilerServices.CallSite, System.Type, dynamic, dynamic>> M.<>o__3.<>p__0""
IL_0006: brtrue.s IL_0043
IL_0008: ldc.i4.0
IL_0009: ldstr ""Test""
IL_000e: ldnull
IL_000f: ldtoken ""M""
IL_0014: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)""
IL_0019: ldc.i4.2
IL_001a: newarr ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo""
IL_001f: dup
IL_0020: ldc.i4.0
IL_0021: ldc.i4.s 33
IL_0023: ldnull
IL_0024: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)""
IL_0029: stelem.ref
IL_002a: dup
IL_002b: ldc.i4.1
IL_002c: ldc.i4.0
IL_002d: ldnull
IL_002e: call ""Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create(Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfoFlags, string)""
IL_0033: stelem.ref
IL_0034: call ""System.Runtime.CompilerServices.CallSiteBinder Microsoft.CSharp.RuntimeBinder.Binder.InvokeMember(Microsoft.CSharp.RuntimeBinder.CSharpBinderFlags, string, System.Collections.Generic.IEnumerable<System.Type>, System.Type, System.Collections.Generic.IEnumerable<Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo>)""
IL_0039: call ""System.Runtime.CompilerServices.CallSite<System.Func<System.Runtime.CompilerServices.CallSite, System.Type, dynamic, dynamic>> System.Runtime.CompilerServices.CallSite<System.Func<System.Runtime.CompilerServices.CallSite, System.Type, dynamic, dynamic>>.Create(System.Runtime.CompilerServices.CallSiteBinder)""
IL_003e: stsfld ""System.Runtime.CompilerServices.CallSite<System.Func<System.Runtime.CompilerServices.CallSite, System.Type, dynamic, dynamic>> M.<>o__3.<>p__0""
IL_0043: ldsfld ""System.Runtime.CompilerServices.CallSite<System.Func<System.Runtime.CompilerServices.CallSite, System.Type, dynamic, dynamic>> M.<>o__3.<>p__0""
IL_0048: ldfld ""System.Func<System.Runtime.CompilerServices.CallSite, System.Type, dynamic, dynamic> System.Runtime.CompilerServices.CallSite<System.Func<System.Runtime.CompilerServices.CallSite, System.Type, dynamic, dynamic>>.Target""
IL_004d: ldsfld ""System.Runtime.CompilerServices.CallSite<System.Func<System.Runtime.CompilerServices.CallSite, System.Type, dynamic, dynamic>> M.<>o__3.<>p__0""
IL_0052: ldtoken ""M""
IL_0057: call ""System.Type System.Type.GetTypeFromHandle(System.RuntimeTypeHandle)""
IL_005c: ldc.i4.2
IL_005d: box ""int""
IL_0062: call ""dynamic M.Test(dynamic)""
IL_0067: callvirt ""dynamic System.Func<System.Runtime.CompilerServices.CallSite, System.Type, dynamic, dynamic>.Invoke(System.Runtime.CompilerServices.CallSite, System.Type, dynamic)""
IL_006c: stfld ""object M.a""
IL_0071: ldarg.0
IL_0072: call ""object..ctor()""
IL_0077: ret
}");
}
[WorkItem(10463, "https://github.com/dotnet/roslyn/issues/10463")]
[Fact]
public void FieldInitializerDynamicInstance()
{
string source = @"
using System;
class M
{
object a = Test((dynamic)2);
object Test(object obj) => obj;
static void Main()
{
Console.Write(new M().a);
}
}
";
// BREAKING CHANGE: The native compiler allowed this (and generated code that will always throw at runtime)
CreateCompilationWithMscorlib45AndCSruntime(source).VerifyDiagnostics(
// (6,16): error CS0236: A field initializer cannot reference the non-static field, method, or property 'M.Test(object)'
// object a = Test((dynamic)2);
Diagnostic(ErrorCode.ERR_FieldInitRefNonstatic, "Test((dynamic)2)").WithArguments("M.Test(object)").WithLocation(6, 16)
);
}
[WorkItem(10463, "https://github.com/dotnet/roslyn/issues/10463")]
[Fact]
public void FieldInitializerDynamicBothStaticInstance()
{
string source = @"
using System;
class M
{
object a = Test((dynamic)2L);
object b = Test((dynamic)2);
static object Test(long obj)
{
Console.Write(""long."");
return obj;
}
object Test(int obj)
{
Console.Write(""int."");
return obj;
}
static void Main()
{
try
{
Console.Write(new M().a);
}
catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException ex)
{
Console.Write(""ex caught"");
}
}
}
";
var compilation = CompileAndVerify(source, new[] { SystemCoreRef, CSharpRef }, expectedOutput: "long.ex caught");
}
[WorkItem(10463, "https://github.com/dotnet/roslyn/issues/10463")]
[Fact]
public void CtorInitializerInstance()
{
string source = @"
using System;
class B
{
public object a;
public B(object obj)
{
this.a = obj;
}
}
class M : B
{
public M() : base((object)Test((dynamic)2))
{
}
object Test(object obj)
{
return obj;
}
static void Main()
{
try
{
Console.Write(new M().a);
}
catch (Microsoft.CSharp.RuntimeBinder.RuntimeBinderException ex)
{
Console.Write(ex.Message);
}
}
}
";
// BREAKING CHANGE: The native compiler allowed this (and generated code that will always throw at runtime)
CreateCompilationWithMscorlib45AndCSruntime(source).VerifyDiagnostics(
// (16,31): error CS0120: An object reference is required for the non-static field, method, or property 'M.Test(object)'
// public M() : base((object)Test((dynamic)2))
Diagnostic(ErrorCode.ERR_ObjectRequired, "Test((dynamic)2)").WithArguments("M.Test(object)").WithLocation(16, 31)
);
}
[WorkItem(10463, "https://github.com/dotnet/roslyn/issues/10463")]
[Fact]
public void StaticCtorInstance()
{
string source = @"
using System;
class M
{
static M()
{
Console.Write((object)Test((dynamic)2));
}
object Test(object obj)
{
return obj;
}
static void Main()
{
}
}
";
// BREAKING CHANGE: The native compiler allowed this (and generated code that will always throw at runtime)
CreateCompilationWithMscorlib45AndCSruntime(source).VerifyDiagnostics(
// (8,31): error CS0120: An object reference is required for the non-static field, method, or property 'M.Test(object)'
// Console.Write((object)Test((dynamic)2));
Diagnostic(ErrorCode.ERR_ObjectRequired, "Test((dynamic)2)").WithArguments("M.Test(object)").WithLocation(8, 31)
);
}
[WorkItem(10463, "https://github.com/dotnet/roslyn/issues/10463")]
[Fact]
public void StaticFieldInstance()
{
string source = @"
class M
{
static object o = (object)Test((dynamic)2);
object Test(object obj)
{
return obj;
}
static void Main()
{
}
}
";
// BREAKING CHANGE: The native compiler allowed this (and generated code that will always throw at runtime)
CreateCompilationWithMscorlib45AndCSruntime(source).VerifyDiagnostics(
// (4,31): error CS0236: A field initializer cannot reference the non-static field, method, or property 'M.Test(object)'
// static object o = (object)Test((dynamic)2);
Diagnostic(ErrorCode.ERR_FieldInitRefNonstatic, "Test((dynamic)2)").WithArguments("M.Test(object)").WithLocation(4, 31)
);
}
[Fact]
public void CallingInstanceDynamicallyFromStaticContext()
{
string source = @"
class B
{
public B(int x)
{
}
}
class C : B
{
int InstanceMethod(int x)
{
return x;
}
static int field = (int)InstanceMethod((dynamic)2);
static int Property
{
get
{
return (int)InstanceMethod((dynamic)2);
}
}
static int Method()
{
return (int)InstanceMethod((dynamic)2);
}
// these are all still static contexts, even though they're related to instance things
int instanceField = (int)InstanceMethod((dynamic)2);
public C(int x) : base((int)InstanceMethod((dynamic)x))
{
}
public C() : this((int)InstanceMethod((dynamic)2))
{
}
}
class M
{
static void Main()
{
// attempting to even load C will cause runtime errors in all cases of calling C.InstanceMethod
System.Console.Write(5);
}
}
";
// BREAKING CHANGE: The native compiler allowed this (and generated code that will always throw at runtime)
CreateCompilationWithMscorlib45AndCSruntime(source).VerifyDiagnostics(
// (16,29): error CS0236: A field initializer cannot reference the non-static field, method, or property 'C.InstanceMethod(int)'
// static int field = (int)InstanceMethod((dynamic)2);
Diagnostic(ErrorCode.ERR_FieldInitRefNonstatic, "InstanceMethod((dynamic)2)").WithArguments("C.InstanceMethod(int)").WithLocation(16, 29),
// (30,30): error CS0236: A field initializer cannot reference the non-static field, method, or property 'C.InstanceMethod(int)'
// int instanceField = (int)InstanceMethod((dynamic)2);
Diagnostic(ErrorCode.ERR_FieldInitRefNonstatic, "InstanceMethod((dynamic)2)").WithArguments("C.InstanceMethod(int)").WithLocation(30, 30),
// (21,25): error CS0120: An object reference is required for the non-static field, method, or property 'C.InstanceMethod(int)'
// return (int)InstanceMethod((dynamic)2);
Diagnostic(ErrorCode.ERR_ObjectRequired, "InstanceMethod((dynamic)2)").WithArguments("C.InstanceMethod(int)").WithLocation(21, 25),
// (26,21): error CS0120: An object reference is required for the non-static field, method, or property 'C.InstanceMethod(int)'
// return (int)InstanceMethod((dynamic)2);
Diagnostic(ErrorCode.ERR_ObjectRequired, "InstanceMethod((dynamic)2)").WithArguments("C.InstanceMethod(int)").WithLocation(26, 21),
// (31,33): error CS0120: An object reference is required for the non-static field, method, or property 'C.InstanceMethod(int)'
// public C(int x) : base((int)InstanceMethod((dynamic)x))
Diagnostic(ErrorCode.ERR_ObjectRequired, "InstanceMethod((dynamic)x)").WithArguments("C.InstanceMethod(int)").WithLocation(31, 33),
// (34,28): error CS0120: An object reference is required for the non-static field, method, or property 'C.InstanceMethod(int)'
// public C() : this((int)InstanceMethod((dynamic)2))
Diagnostic(ErrorCode.ERR_ObjectRequired, "InstanceMethod((dynamic)2)").WithArguments("C.InstanceMethod(int)").WithLocation(34, 28)
);
}
[Fact]
public void CallingInstanceDynamicallyFromStaticContextWithTypeName()
{
// Very similar to CallingInstanceDynamicallyFromStaticContext, but every call to `InstanceMethod` is now `C.InstanceMethod`
// The native compiler allows both cases, so it's an interesting backcompat case:
// The spec (as of 2016-05-13, it may be changed) explicitly disallows `C.InstanceMethod`,
// but doesn't say for just `InstanceMethod` (in a way that implies it should be allowed).
// Roslyn disallows both cases.
string source = @"
class B
{
public B(int x)
{
}
}
class C : B
{
int InstanceMethod(int x)
{
return x;
}
static int field = (int)C.InstanceMethod((dynamic)2);
static int Property
{
get
{
return (int)C.InstanceMethod((dynamic)2);
}
}
static int Method()
{
return (int)C.InstanceMethod((dynamic)2);
}
// these are all still static contexts, even though they're related to instance things
int instanceField = (int)C.InstanceMethod((dynamic)2);
public C(int x) : base((int)C.InstanceMethod((dynamic)x))
{
}
public C() : this((int)C.InstanceMethod((dynamic)2))
{
}
}
class M
{
static void Main()
{
// attempting to even load C will cause runtime errors in all cases of calling C.InstanceMethod
System.Console.Write(5);
}
}
";
// BREAKING CHANGE: The native compiler allowed this (and generated code that will always throw at runtime)
CreateCompilationWithMscorlib45AndCSruntime(source).VerifyDiagnostics(
// (16,29): error CS0120: An object reference is required for the non-static field, method, or property 'C.InstanceMethod(int)'
// static int field = (int)C.InstanceMethod((dynamic)2);
Diagnostic(ErrorCode.ERR_ObjectRequired, "C.InstanceMethod((dynamic)2)").WithArguments("C.InstanceMethod(int)").WithLocation(16, 29),
// (30,30): error CS0120: An object reference is required for the non-static field, method, or property 'C.InstanceMethod(int)'
// int instanceField = (int)C.InstanceMethod((dynamic)2);
Diagnostic(ErrorCode.ERR_ObjectRequired, "C.InstanceMethod((dynamic)2)").WithArguments("C.InstanceMethod(int)").WithLocation(30, 30),
// (21,25): error CS0120: An object reference is required for the non-static field, method, or property 'C.InstanceMethod(int)'
// return (int)C.InstanceMethod((dynamic)2);
Diagnostic(ErrorCode.ERR_ObjectRequired, "C.InstanceMethod((dynamic)2)").WithArguments("C.InstanceMethod(int)").WithLocation(21, 25),
// (26,21): error CS0120: An object reference is required for the non-static field, method, or property 'C.InstanceMethod(int)'
// return (int)C.InstanceMethod((dynamic)2);
Diagnostic(ErrorCode.ERR_ObjectRequired, "C.InstanceMethod((dynamic)2)").WithArguments("C.InstanceMethod(int)").WithLocation(26, 21),
// (31,33): error CS0120: An object reference is required for the non-static field, method, or property 'C.InstanceMethod(int)'
// public C(int x) : base((int)C.InstanceMethod((dynamic)x))
Diagnostic(ErrorCode.ERR_ObjectRequired, "C.InstanceMethod((dynamic)x)").WithArguments("C.InstanceMethod(int)").WithLocation(31, 33),
// (34,28): error CS0120: An object reference is required for the non-static field, method, or property 'C.InstanceMethod(int)'
// public C() : this((int)C.InstanceMethod((dynamic)2))
Diagnostic(ErrorCode.ERR_ObjectRequired, "C.InstanceMethod((dynamic)2)").WithArguments("C.InstanceMethod(int)").WithLocation(34, 28)
);
}
}
}
......@@ -3461,6 +3461,32 @@ interface I
);
}
[Fact, WorkItem(9945, "https://github.com/dotnet/roslyn/issues/9945")]
public void DynamicGetOnlyPropertyIndexer()
{
string source = @"
class Program
{
static void Main()
{
I i = null;
System.Type t = i[null].GetType();
}
interface I
{
dynamic this[string s] { set; }
}
}
";
var compilation = CreateCompilationWithMscorlib(source, new[] { CSharpRef, SystemCoreRef }, options: TestOptions.DebugDll);
compilation.VerifyEmitDiagnostics(
// (7,25): error CS0154: The property or indexer 'Program.I.this[string]' cannot be used in this context because it lacks the get accessor
// System.Type t = i[null].GetType();
Diagnostic(ErrorCode.ERR_PropertyLacksGet, "i[null]").WithArguments("Program.I.this[string]").WithLocation(7, 25)
);
}
[ClrOnlyFact(ClrOnlyReason.Ilasm)]
public void IncorrectArrayLength()
{
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册