-
Notifications
You must be signed in to change notification settings - Fork 4.1k
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
Verify synthesized RequiresLocationAttribute
cannot be accessed by fnptrs
#69328
Merged
jjonescz
merged 7 commits into
dotnet:main
from
jjonescz:RefReadonly-24-AttributeEmitTests
Aug 11, 2023
Merged
Changes from 1 commit
Commits
Show all changes
7 commits
Select commit
Hold shift + click to select a range
a745c27
Verify synthesized `RequiresLocationAttribute` cannot be accessed by …
jjonescz 036a91b
Verify which attribute is emitted as modopt
jjonescz 2bddd9a
Test type forwarding
jjonescz 6f44f7b
Remove unnecessary `using`
jjonescz e259e72
Verify modopt's assembly name
jjonescz 2a1aa53
Merge branch 'main' into RefReadonly-24-AttributeEmitTests
jjonescz 35f669e
Fix copy-paste mistake
jjonescz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -1191,13 +1191,158 @@ public unsafe void M(delegate*<ref readonly int, void> p) { } | |
} | ||
"""; | ||
var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll); | ||
comp.MakeTypeMissing(WellKnownType.System_Runtime_CompilerServices_RequiresLocationAttribute); | ||
comp.VerifyDiagnostics( | ||
// (3,36): error CS0518: Predefined type 'System.Runtime.CompilerServices.RequiresLocationAttribute' is not defined or imported | ||
// public unsafe void M(delegate*<ref readonly int, void> p) { } | ||
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(3, 36)); | ||
} | ||
|
||
[Fact] | ||
public void FunctionPointer_NoAttribute_PlusNormalMethod() | ||
{ | ||
var source = """ | ||
class C | ||
{ | ||
public unsafe void M1(delegate*<ref readonly int, void> p) { } | ||
public void M2(ref readonly int p) { } | ||
} | ||
"""; | ||
var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll); | ||
comp.VerifyDiagnostics( | ||
// (3,37): error CS0518: Predefined type 'System.Runtime.CompilerServices.RequiresLocationAttribute' is not defined or imported | ||
// public unsafe void M1(delegate*<ref readonly int, void> p) { } | ||
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(3, 37)); | ||
} | ||
|
||
[Fact] | ||
public void FunctionPointer_InternalAttribute() | ||
{ | ||
// Attribute is synthesized for Assembly1, but it's not visible to Assembly2. | ||
var source1 = """ | ||
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("Assembly2")] | ||
internal class C | ||
{ | ||
public void M(ref readonly int p) { } | ||
} | ||
"""; | ||
var comp1 = CreateCompilation(source1, assemblyName: "Assembly1").VerifyDiagnostics(); | ||
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. Similar feedback about all the |
||
var comp1Ref = comp1.EmitToImageReference(); | ||
var source2 = """ | ||
class D | ||
{ | ||
public unsafe object M(delegate*<ref readonly int, void> p) | ||
{ | ||
var c = new C(); | ||
int x = 5; | ||
c.M(in x); | ||
var attr = new System.Runtime.CompilerServices.RequiresLocationAttribute(); | ||
return attr; | ||
} | ||
} | ||
"""; | ||
var comp2 = CreateCompilation(source2, new[] { comp1Ref }, assemblyName: "Assembly2", options: TestOptions.UnsafeDebugDll); | ||
comp2.VerifyDiagnostics( | ||
// (3,38): error CS0518: Predefined type 'System.Runtime.CompilerServices.RequiresLocationAttribute' is not defined or imported | ||
// public unsafe object M(delegate*<ref readonly int, void> p) | ||
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(3, 38), | ||
// (8,56): error CS0234: The type or namespace name 'RequiresLocationAttribute' does not exist in the namespace 'System.Runtime.CompilerServices' (are you missing an assembly reference?) | ||
// var attr = new System.Runtime.CompilerServices.RequiresLocationAttribute(); | ||
Diagnostic(ErrorCode.ERR_DottedTypeNameNotFoundInNS, "RequiresLocationAttribute").WithArguments("RequiresLocationAttribute", "System.Runtime.CompilerServices").WithLocation(8, 56)); | ||
|
||
// Assembly1 defines the attribute in source and has IVT to Assembly2, so the attribute is visible to Assembly2. | ||
var comp1b = CreateCompilation(new[] { source1, RequiresLocationAttributeDefinition }, assemblyName: "Assembly1").VerifyDiagnostics(); | ||
var comp1bRef = comp1b.EmitToImageReference(); | ||
var comp2b = CreateCompilation(source2, new[] { comp1bRef }, assemblyName: "Assembly2", options: TestOptions.UnsafeDebugDll); | ||
comp2b.VerifyDiagnostics(); | ||
|
||
// Assembly1 defines the attribute in source but doesn't have IVT to Assembly3, so the attribute isn't visible to Assembly3. | ||
var source3 = """ | ||
class D | ||
{ | ||
public unsafe object M(delegate*<ref readonly int, void> p) | ||
{ | ||
var attr = new System.Runtime.CompilerServices.RequiresLocationAttribute(); | ||
return attr; | ||
} | ||
} | ||
"""; | ||
var comp3 = CreateCompilation(source3, new[] { comp1bRef }, assemblyName: "Assembly3", options: TestOptions.UnsafeDebugDll); | ||
comp3.VerifyDiagnostics( | ||
// (3,38): error CS0518: Predefined type 'System.Runtime.CompilerServices.RequiresLocationAttribute' is not defined or imported | ||
// public unsafe object M(delegate*<ref readonly int, void> p) | ||
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "ref readonly int").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(3, 38), | ||
// (5,56): error CS0122: 'RequiresLocationAttribute' is inaccessible due to its protection level | ||
// var attr = new System.Runtime.CompilerServices.RequiresLocationAttribute(); | ||
Diagnostic(ErrorCode.ERR_BadAccess, "RequiresLocationAttribute").WithArguments("System.Runtime.CompilerServices.RequiresLocationAttribute").WithLocation(5, 56)); | ||
} | ||
|
||
[Fact] | ||
public void FunctionPointer_DefineManually_LaterDefinedInRuntime() | ||
{ | ||
// Library defines an API with function pointer, manually declaring the attribute. | ||
var source1 = """ | ||
public class C | ||
{ | ||
public unsafe void M(delegate*<ref readonly int, void> f) | ||
{ | ||
int x = 123; | ||
f(in x); | ||
} | ||
} | ||
"""; | ||
var comp1v1 = CreateCompilation(new[] { source1, RequiresLocationAttributeDefinition }, assemblyName: "Assembly1", options: TestOptions.UnsafeReleaseDll); | ||
comp1v1.VerifyDiagnostics(); | ||
var comp1v1Ref = comp1v1.EmitToImageReference(); | ||
|
||
// Consumer can use the API. | ||
var source2 = """ | ||
public class D | ||
{ | ||
public unsafe void M() | ||
{ | ||
new C().M(&F); | ||
} | ||
static void F(ref readonly int x) => System.Console.Write("F" + x); | ||
} | ||
"""; | ||
var comp2 = CreateCompilation(source2, new[] { comp1v1Ref }, options: TestOptions.UnsafeReleaseDll).VerifyDiagnostics(); | ||
var comp2Ref = comp2.EmitToImageReference(); | ||
|
||
var source3 = """ | ||
try | ||
{ | ||
new D().M(); | ||
} | ||
catch (System.MissingMethodException e) | ||
{ | ||
System.Console.Write(e.Message); | ||
} | ||
"""; | ||
CompileAndVerify(source3, new[] { comp1v1Ref, comp2Ref }, expectedOutput: "F123").VerifyDiagnostics(); | ||
|
||
// .NET runtime declares the attribute. | ||
var source4 = """ | ||
namespace System.Runtime.CompilerServices | ||
{ | ||
[AttributeUsage(AttributeTargets.Parameter, AllowMultiple = false, Inherited = false)] | ||
public sealed class RequiresLocationAttribute : Attribute | ||
{ | ||
} | ||
} | ||
"""; | ||
var comp4 = CreateCompilation(source4).VerifyDiagnostics(); | ||
var comp4Ref = comp4.EmitToImageReference(); | ||
|
||
// Library is recompiled against the newest runtime. | ||
var comp1v2 = CreateCompilation(source1, new[] { comp4Ref }, assemblyName: "Assembly1", options: TestOptions.UnsafeReleaseDll); | ||
comp1v2.VerifyDiagnostics(); | ||
var comp1v2Ref = comp1v2.EmitToImageReference(); | ||
|
||
// That breaks the consumer. | ||
CompileAndVerify(source3, new[] { comp1v2Ref, comp2Ref, comp4Ref }, | ||
expectedOutput: "Method not found: 'Void C.M(Void (Int32 ByRef))'.").VerifyDiagnostics(); | ||
} | ||
|
||
jjonescz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
[Fact] | ||
public void FunctionPointer_Local() | ||
{ | ||
|
@@ -1231,7 +1376,6 @@ unsafe void M() | |
} | ||
"""; | ||
var comp = CreateCompilation(source, options: TestOptions.UnsafeDebugDll); | ||
comp.MakeTypeMissing(WellKnownType.System_Runtime_CompilerServices_RequiresLocationAttribute); | ||
comp.VerifyDiagnostics( | ||
// (5,19): error CS0518: Predefined type 'System.Runtime.CompilerServices.RequiresLocationAttribute' is not defined or imported | ||
// delegate*<ref readonly int, void> p = null; | ||
|
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
The core
CreateCompilation
helper is expected to roll forward to the latest target framework as we move forward. At the moment this references thenet7.0
assemblies but will move tonet8.0
(likely early 2024). At that point the test will fail because this will succeed sinceRequiresLocationAttribute
will be available. Think this test should specifyTargetFramework.Net70
explicitly to avoid that future issue.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.
Is that right? Seems that the default target framework is
netstandard2.0
. Otherwise, I would probably need to change a lot of tests in this file because for example all function pointer tests include the attribute definition as source.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.
My mistake. Your correct this defaults to
TargteFramework.Standard
notTargetFramework.Latest
.