-
Notifications
You must be signed in to change notification settings - Fork 4k
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
Suppress dynamic access to instance indexers off of types. #11677
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3550,5 +3550,260 @@ .maxstack 8 | |
Assert.Equal(typeGConstructed, typeD.GetMember<FieldSymbol>("ExtraTrue").Type); | ||
Assert.Equal(typeGConstructed, typeD.GetMember<FieldSymbol>("ExtraFalse").Type); | ||
} | ||
|
||
[ClrOnlyFact(ClrOnlyReason.Ilasm)] | ||
[WorkItem(204561, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=204561&_a=edit")] | ||
public void SuppressDynamicIndexerAccessOffOfType_01() | ||
{ | ||
var iLSource = @" | ||
.assembly extern mscorlib | ||
{ | ||
.publickeytoken = (B7 7A 5C 56 19 34 E0 89 ) // .z\V.4.. | ||
.ver 4:0:0:0 | ||
} | ||
|
||
.assembly Microsoft.Office.Interop.Excel | ||
{ | ||
.custom instance void [mscorlib]System.Runtime.InteropServices.ImportedFromTypeLibAttribute::.ctor(string) = ( 01 00 05 45 78 63 65 6C 00 00 ) // ...Excel.. | ||
.custom instance void [mscorlib]System.Runtime.InteropServices.PrimaryInteropAssemblyAttribute::.ctor(int32, | ||
int32) = ( 01 00 01 00 00 00 08 00 00 00 00 00 ) | ||
.custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = ( 01 00 24 30 30 30 32 30 38 31 33 2D 30 30 30 30 // ..$00020813-0000 | ||
2D 30 30 30 30 2D 63 30 30 30 2D 30 30 30 30 30 // -0000-c000-00000 | ||
30 30 30 30 30 34 36 00 00 ) // 0000046.. | ||
.custom instance void [mscorlib]System.Runtime.InteropServices.TypeLibVersionAttribute::.ctor(int32, | ||
int32) = ( 01 00 01 00 00 00 08 00 00 00 00 00 ) | ||
.hash algorithm 0x00008004 | ||
.ver 15:0:0:0 | ||
} | ||
.module Excel.dll | ||
// MVID: {C7C599B3-5C80-48BC-9637-7CADFEF6DEB8} | ||
.imagebase 0x00400000 | ||
.file alignment 0x00001000 | ||
.stackreserve 0x00100000 | ||
.subsystem 0x0003 // WINDOWS_CUI | ||
.corflags 0x00000009 // ILONLY | ||
// Image base: 0x050E0000 | ||
|
||
.class interface public abstract auto ansi import Microsoft.Office.Interop.Excel.Worksheet | ||
implements Microsoft.Office.Interop.Excel._Worksheet | ||
{ | ||
.custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = ( 01 00 24 30 30 30 32 30 38 44 38 2D 30 30 30 30 // ..$000208D8-0000 | ||
2D 30 30 30 30 2D 43 30 30 30 2D 30 30 30 30 30 // -0000-C000-00000 | ||
30 30 30 30 30 34 36 00 00 ) // 0000046.. | ||
} // end of class Microsoft.Office.Interop.Excel.Worksheet | ||
|
||
.class interface public abstract auto ansi import Microsoft.Office.Interop.Excel._Worksheet | ||
{ | ||
.custom instance void [mscorlib]System.Runtime.InteropServices.TypeLibTypeAttribute::.ctor(int16) = ( 01 00 C0 10 00 00 ) | ||
.custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = ( 01 00 24 30 30 30 32 30 38 44 38 2D 30 30 30 30 // ..$000208D8-0000 | ||
2D 30 30 30 30 2D 43 30 30 30 2D 30 30 30 30 30 // -0000-C000-00000 | ||
30 30 30 30 30 34 36 00 00 ) // 0000046.. | ||
|
||
.method public hidebysig newslot specialname abstract virtual | ||
instance class Microsoft.Office.Interop.Excel.Range | ||
marshal( interface ) | ||
get_Range([in] object marshal( struct) Cell1, | ||
[in][opt] object marshal( struct) Cell2) runtime managed internalcall | ||
{ | ||
.custom instance void [mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32) = ( 01 00 C5 00 00 00 00 00 ) | ||
} // end of method _Worksheet::get_Range | ||
|
||
.property class Microsoft.Office.Interop.Excel.Range | ||
Range(object, | ||
object) | ||
{ | ||
.custom instance void [mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32) = ( 01 00 C5 00 00 00 00 00 ) | ||
.get instance class Microsoft.Office.Interop.Excel.Range Microsoft.Office.Interop.Excel._Worksheet::get_Range(object, | ||
object) | ||
} // end of property _Worksheet::Range | ||
|
||
.method public hidebysig newslot specialname abstract virtual | ||
instance class Microsoft.Office.Interop.Excel.Range | ||
marshal( interface ) | ||
MRange([in] object marshal( struct) Cell1, | ||
[in][opt] object marshal( struct) Cell2) runtime managed internalcall | ||
{ | ||
.custom instance void [mscorlib]System.Runtime.InteropServices.DispIdAttribute::.ctor(int32) = ( 01 00 C5 00 00 00 00 00 ) | ||
} // end of method _Worksheet::get_Range | ||
} | ||
|
||
.class interface public abstract auto ansi import Microsoft.Office.Interop.Excel.Range | ||
implements [mscorlib]System.Collections.IEnumerable | ||
{ | ||
.custom instance void [mscorlib]System.Runtime.InteropServices.InterfaceTypeAttribute::.ctor(int16) = ( 01 00 02 00 00 00 ) | ||
.custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = ( 01 00 08 5F 44 65 66 61 75 6C 74 00 00 ) // ..._Default.. | ||
.custom instance void [mscorlib]System.Runtime.InteropServices.GuidAttribute::.ctor(string) = ( 01 00 24 30 30 30 32 30 38 34 36 2D 30 30 30 30 // ..$00020846-0000 | ||
2D 30 30 30 30 2D 43 30 30 30 2D 30 30 30 30 30 // -0000-C000-00000 | ||
30 30 30 30 30 34 36 00 00 ) // 0000046.. | ||
.custom instance void [mscorlib]System.Runtime.InteropServices.TypeLibTypeAttribute::.ctor(int16) = ( 01 00 00 10 00 00 ) | ||
} | ||
"; | ||
|
||
MetadataReference reference = CompileIL(iLSource, appendDefaultHeader: false, embedInteropTypes: false); | ||
|
||
string consumer1 = @" | ||
using Microsoft.Office.Interop.Excel; | ||
|
||
class Test | ||
{ | ||
public static void Main() | ||
{ | ||
dynamic x = 1; | ||
dynamic y = 1; | ||
|
||
var z2 = Worksheet.MRange(x, y); | ||
} | ||
} | ||
"; | ||
|
||
var compilation1 = CreateCompilationWithMscorlib(consumer1, options: TestOptions.ReleaseExe, | ||
references: new MetadataReference[] { reference, CSharpRef, SystemCoreRef }); | ||
|
||
compilation1.VerifyDiagnostics( | ||
// (11,18): error CS0120: An object reference is required for the non-static field, method, or property '_Worksheet.MRange(object, object)' | ||
// var z2 = Worksheet.MRange(x, y); | ||
Diagnostic(ErrorCode.ERR_ObjectRequired, "Worksheet.MRange(x, y)").WithArguments("Microsoft.Office.Interop.Excel._Worksheet.MRange(object, object)").WithLocation(11, 18) | ||
); | ||
|
||
string consumer2 = @" | ||
using Microsoft.Office.Interop.Excel; | ||
|
||
class Test | ||
{ | ||
public static void Main() | ||
{ | ||
dynamic x = 1; | ||
dynamic y = 1; | ||
var z1 = Worksheet.Range[x, y]; | ||
} | ||
} | ||
"; | ||
|
||
var compilation2 = CreateCompilationWithMscorlib(consumer2, options: TestOptions.ReleaseExe, | ||
references: new MetadataReference[] { reference, CSharpRef, SystemCoreRef }); | ||
|
||
compilation2.VerifyDiagnostics( | ||
// (10,18): error CS0120: An object reference is required for the non-static field, method, or property '_Worksheet.Range[object, object]' | ||
// var z1 = Worksheet.Range[x, y]; | ||
Diagnostic(ErrorCode.ERR_ObjectRequired, "Worksheet.Range[x, y]").WithArguments("Microsoft.Office.Interop.Excel._Worksheet.Range[object, object]").WithLocation(10, 18) | ||
); | ||
} | ||
|
||
[ClrOnlyFact(ClrOnlyReason.Ilasm)] | ||
[WorkItem(204561, "https://devdiv.visualstudio.com/DefaultCollection/DevDiv/_workitems?id=204561&_a=edit")] | ||
public void SuppressDynamicIndexerAccessOffOfType_02() | ||
{ | ||
var iLSource = @" | ||
.class public auto ansi WithIndexer | ||
extends [mscorlib]System.Object | ||
{ | ||
.method public specialname rtspecialname | ||
instance void .ctor() cil managed | ||
{ | ||
// Code size 7 (0x7) | ||
.maxstack 8 | ||
IL_0000: ldarg.0 | ||
IL_0001: call instance void [mscorlib]System.Object::.ctor() | ||
IL_0006: ret | ||
} // end of method WithIndexer::.ctor | ||
|
||
.method public specialname static object | ||
get_Indexer(object x, | ||
object y) cil managed | ||
{ | ||
// Code size 18 (0x12) | ||
.maxstack 1 | ||
.locals init (object V_0) | ||
IL_0000: nop | ||
IL_0001: ldstr ""Indexer"" | ||
IL_0006: call void [mscorlib]System.Console::WriteLine(string) | ||
IL_000b: nop | ||
IL_000c: ldnull | ||
IL_000d: stloc.0 | ||
IL_000e: br.s IL_0010 | ||
|
||
IL_0010: ldloc.0 | ||
IL_0011: ret | ||
} // end of method WithIndexer::get_Indexer | ||
|
||
.method public specialname static void | ||
set_Indexer(object x, | ||
object y, | ||
object 'value') cil managed | ||
{ | ||
// Code size 2 (0x2) | ||
.maxstack 8 | ||
IL_0000: nop | ||
IL_0001: ret | ||
} // end of method WithIndexer::set_Indexer | ||
|
||
.method public static object MIndexer(object x, | ||
object y) cil managed | ||
{ | ||
// Code size 18 (0x12) | ||
.maxstack 1 | ||
.locals init (object V_0) | ||
IL_0000: nop | ||
IL_0001: ldstr ""MIndexer"" | ||
IL_0006: call void [mscorlib]System.Console::WriteLine(string) | ||
IL_000b: nop | ||
IL_000c: ldnull | ||
IL_000d: stloc.0 | ||
IL_000e: br.s IL_0010 | ||
|
||
IL_0010: ldloc.0 | ||
IL_0011: ret | ||
} // end of method WithIndexer::MIndexer | ||
|
||
.property object Indexer(object, | ||
object) | ||
{ | ||
.get object WithIndexer::get_Indexer(object, | ||
object) | ||
.set void WithIndexer::set_Indexer(object, | ||
object, | ||
object) | ||
} // end of property WithIndexer::Indexer | ||
} // end of class WithIndexer | ||
"; | ||
|
||
MetadataReference reference = CompileIL(iLSource, appendDefaultHeader: true, embedInteropTypes: false); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can an assembly of this structure only be created in IL? Just asking because if it could also be created in VB it may be interesting to have a test with VB code to ensure reasonable interop. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I prefer to test from IL in this case. As you can see, there is no interop with indexed property in this case and that is the scenario we are interested about. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I suppose producing a binding error isn't interop. Sounds good. |
||
|
||
string consumer1 = @" | ||
class Test | ||
{ | ||
public static void Main() | ||
{ | ||
dynamic x = 1; | ||
dynamic y = 1; | ||
var z2 = WithIndexer.MIndexer(x, y); | ||
} | ||
}"; | ||
|
||
var compilation1 = CreateCompilationWithMscorlib(consumer1, options: TestOptions.ReleaseExe, | ||
references: new MetadataReference[] { reference, CSharpRef, SystemCoreRef }); | ||
|
||
CompileAndVerify(compilation1, expectedOutput: "MIndexer").VerifyDiagnostics(); | ||
|
||
string consumer2 = @" | ||
class Test | ||
{ | ||
public static void Main() | ||
{ | ||
dynamic x = 1; | ||
dynamic y = 1; | ||
var z1 = WithIndexer.Indexer[x, y]; | ||
} | ||
}"; | ||
|
||
var compilation2 = CreateCompilationWithMscorlib(consumer2, options: TestOptions.ReleaseExe, | ||
references: new MetadataReference[] { reference, CSharpRef, SystemCoreRef }); | ||
|
||
compilation2.VerifyDiagnostics( | ||
// (8,30): error CS1545: Property, indexer, or event 'WithIndexer.Indexer[object, object]' is not supported by the language; try directly calling accessor methods 'WithIndexer.get_Indexer(object, object)' or 'WithIndexer.set_Indexer(object, object, object)' | ||
// var z1 = WithIndexer.Indexer[x, y]; | ||
Diagnostic(ErrorCode.ERR_BindToBogusProp2, "Indexer").WithArguments("WithIndexer.Indexer[object, object]", "WithIndexer.get_Indexer(object, object)", "WithIndexer.set_Indexer(object, object, object)").WithLocation(8, 30) | ||
); | ||
} | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why the double conversion:
(MethodSymbol)(object)
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Compiler refused to convert from type parameter directly.