-
Notifications
You must be signed in to change notification settings - Fork 5.1k
Description
Method<string>();
Type Method<TUnknown>()
{
// Should WARN - TUnknown does have All annotation
return typeof(TRequires<TUnknown>);
}
class TRequires<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.All)] T>
{
}
The able produces IL2091 in the trimmer, but doesn't produce it in the analyzer. The bug seems to be that we don't process generic parameter annotations in a typeof
.
Also happens for a declaration of a local variable:
void Method<TUnknown>()
{
// Trimmer produces IL2091 here, analyzer doesn't
TRequires<TUnknown> a;
}
Note that for local variables NativeAOT doesn't produce the warning either - see the comment here for why:
runtime/src/tools/illink/test/Mono.Linker.Tests.Cases/DataFlow/GenericParameterWarningLocation.cs
Lines 12 to 28 in 7f81848
// NativeAOT differences in behavior: | |
// | |
// Validation of generic parameters only matters if the instantiation can be used to run code with the substituted type. | |
// So for generic methods the validation has to happen basically always (since any access to the method can lead to the code | |
// of the method executing eventually). | |
// For generic types though the situation is different. Code on the type can only run if the type is instantiated (new) | |
// or if static members are accessed on it (method calls, or fields accesses both can lead to static .cctor execution). | |
// Others usages of the type cannot themselves lead to code execution in the type, and thus don't need to be validated. | |
// Currently linker and analyzer both validate every time there's a type occurrence in the code. | |
// NativeAOT on the other hand only validates the cases which can lead to code execution (this is partially because the compiler | |
// doesn't care about the type in other situations really). | |
// So for example local variables of a given type, or method parameters of that type alone will not cause code execution | |
// inside that type and thus won't be validated by NativeAOT compiler. | |
// | |
// Below this explanation/fact is referred to as "NativeAOT_StorageSpaceType" | |
// Storage space - declaring a storage space as having a specific type doesn't in itself do anything with that type as per | |
// the above description. |
We should figure out if analyzer needs to produce the warning or not.
Another situation is a static field access:
TRequires<TUnknown>.Field; // Should warn
Yet another situation - expression trees:
Expression<Func<string>> a = () => TRequires<TUnknown>.Field
And then type checks (NativeAOT doesn't warn here, see the link above):
if (value is TRequires<TUnknown>) {}
var a = value as TRequires<TUnknown>;
Catch and filter expressions (NativeAOT doesn't warn):
try {}
catch (TRequires<TUnknown>) {}
catch (Exception ex) when (ex is TRequires<TUnknown>) {}
Nested generic for methods:
GenericMethod<Generic1<Generic2<TRequires<TUnknown>>>();
Similarly nested generics don't cause DAM marking and thus diagnostics:
GenericMethod<Generic1<Generic2<TRequires<TypeWIthRUCMethod>>>(); // Should produce IL2026
Metadata
Metadata
Assignees
Labels
Type
Projects
Status