Skip to content
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

Add more DataFlow tests from linker to NativeAOT #72777

Merged
merged 7 commits into from
Aug 1, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ internal static bool TryGetRequiresAttribute(TypeSystemEntity member, string req
decoded = ecmaMethod.GetDecodedCustomAttribute("System.Diagnostics.CodeAnalysis", requiresAttributeName);
break;
case MetadataType type:
var ecmaType = type as EcmaType;
var ecmaType = type.GetTypeDefinition() as EcmaType;
if (ecmaType == null)
return false;
decoded = ecmaType.GetDecodedCustomAttribute("System.Diagnostics.CodeAnalysis", requiresAttributeName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -227,6 +227,10 @@ public static bool IsTypeInterestingForDataflow(TypeDesc type)
if (type.IsWellKnownType(WellKnownType.String))
return true;

// ByRef over an interesting type is itself interesting
if (type is ByRefType byRefType)
type = byRefType.ParameterType;

if (!type.IsDefType)
return false;

Expand Down Expand Up @@ -584,7 +588,7 @@ protected override TypeAnnotations CreateValueFromKey(TypeDesc key)
{
if (typeGenericParameterAnnotations == null)
typeGenericParameterAnnotations = new DynamicallyAccessedMemberTypes[ecmaType.Instantiation.Length];
typeGenericParameterAnnotations[genericParameter.Index] = annotation;
typeGenericParameterAnnotations[genericParameterIndex] = annotation;
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -993,18 +993,7 @@ private void ScanIndirectStore(
StackSlot valueToStore = PopUnknown(currentStack, 1, methodBody, offset);
StackSlot destination = PopUnknown(currentStack, 1, methodBody, offset);

foreach (var uniqueDestination in destination.Value)
{
if (uniqueDestination is FieldValue fieldDestination)
{
HandleStoreField(methodBody, offset, fieldDestination, valueToStore.Value);
}
else if (uniqueDestination is MethodParameterValue parameterDestination)
{
HandleStoreParameter(methodBody, offset, parameterDestination, valueToStore.Value);
}
}

StoreInReference(destination.Value, valueToStore.Value, methodBody, offset, locals, curBasicBlock);
}

/// <summary>
Expand Down Expand Up @@ -1237,6 +1226,14 @@ private void HandleCall(
ValueNodeList methodArguments = PopCallArguments(currentStack, calledMethod, callingMethodBody, isNewObj,
offset, out newObjValue);

// Multi-dimensional array access is represented as a call to a special Get method on the array (runtime provided method)
// We don't track multi-dimensional arrays in any way, so return unknown value.
if (calledMethod is ArrayMethod { Kind: ArrayMethodKind.Get })
{
currentStack.Push(new StackSlot(UnknownValue.Instance));
return;
}
vitek-karas marked this conversation as resolved.
Show resolved Hide resolved

var dereferencedMethodParams = new List<MultiValue>();
foreach (var argument in methodArguments)
dereferencedMethodParams.Add(DereferenceValue(argument, locals, ref interproceduralState));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,20 +26,20 @@ public static void AddDependenciesDueToCustomAttributes(ref DependencyList depen
MethodDefinition methodDef = reader.GetMethodDefinition(methodHandle);

// Handle custom attributes on the method
AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, methodDef.GetCustomAttributes());
AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, methodDef.GetCustomAttributes(), method);

// Handle custom attributes on method parameters
foreach (ParameterHandle parameterHandle in methodDef.GetParameters())
{
Parameter parameter = reader.GetParameter(parameterHandle);
AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, parameter.GetCustomAttributes());
AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, parameter.GetCustomAttributes(), method);
}

// Handle custom attributes on generic method parameters
foreach (GenericParameterHandle genericParameterHandle in methodDef.GetGenericParameters())
{
GenericParameter parameter = reader.GetGenericParameter(genericParameterHandle);
AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, parameter.GetCustomAttributes());
AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, parameter.GetCustomAttributes(), method);
vitek-karas marked this conversation as resolved.
Show resolved Hide resolved
}

// We don't model properties and events as separate entities within the compiler, so ensuring
Expand All @@ -59,7 +59,7 @@ public static void AddDependenciesDueToCustomAttributes(ref DependencyList depen
PropertyAccessors accessors = property.GetAccessors();

if (accessors.Getter == methodHandle || accessors.Setter == methodHandle)
AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, property.GetCustomAttributes());
AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, property.GetCustomAttributes(), new PropertyPseudoDesc((EcmaType)method.OwningType, propertyHandle));
}

foreach (EventDefinitionHandle eventHandle in declaringType.GetEvents())
Expand All @@ -68,7 +68,7 @@ public static void AddDependenciesDueToCustomAttributes(ref DependencyList depen
EventAccessors accessors = @event.GetAccessors();

if (accessors.Adder == methodHandle || accessors.Remover == methodHandle || accessors.Raiser == methodHandle)
AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, @event.GetCustomAttributes());
AddDependenciesDueToCustomAttributes(ref dependencies, factory, method.Module, @event.GetCustomAttributes(), new EventPseudoDesc((EcmaType)method.OwningType, eventHandle));
}
}
}
Expand All @@ -77,32 +77,32 @@ public static void AddDependenciesDueToCustomAttributes(ref DependencyList depen
{
MetadataReader reader = type.MetadataReader;
TypeDefinition typeDef = reader.GetTypeDefinition(type.Handle);
AddDependenciesDueToCustomAttributes(ref dependencies, factory, type.EcmaModule, typeDef.GetCustomAttributes());
AddDependenciesDueToCustomAttributes(ref dependencies, factory, type.EcmaModule, typeDef.GetCustomAttributes(), type);

// Handle custom attributes on generic type parameters
foreach (GenericParameterHandle genericParameterHandle in typeDef.GetGenericParameters())
{
GenericParameter parameter = reader.GetGenericParameter(genericParameterHandle);
AddDependenciesDueToCustomAttributes(ref dependencies, factory, type.EcmaModule, parameter.GetCustomAttributes());
AddDependenciesDueToCustomAttributes(ref dependencies, factory, type.EcmaModule, parameter.GetCustomAttributes(), type);
}
}

public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaField field)
{
FieldDefinition fieldDef = field.MetadataReader.GetFieldDefinition(field.Handle);
AddDependenciesDueToCustomAttributes(ref dependencies, factory, field.Module, fieldDef.GetCustomAttributes());
AddDependenciesDueToCustomAttributes(ref dependencies, factory, field.Module, fieldDef.GetCustomAttributes(), field);
}

public static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaAssembly assembly)
{
AssemblyDefinition asmDef = assembly.MetadataReader.GetAssemblyDefinition();
AddDependenciesDueToCustomAttributes(ref dependencies, factory, assembly, asmDef.GetCustomAttributes());
AddDependenciesDueToCustomAttributes(ref dependencies, factory, assembly, asmDef.GetCustomAttributes(), assembly);

ModuleDefinition moduleDef = assembly.MetadataReader.GetModuleDefinition();
AddDependenciesDueToCustomAttributes(ref dependencies, factory, assembly, moduleDef.GetCustomAttributes());
AddDependenciesDueToCustomAttributes(ref dependencies, factory, assembly, moduleDef.GetCustomAttributes(), assembly);
}

private static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaModule module, CustomAttributeHandleCollection attributeHandles)
private static void AddDependenciesDueToCustomAttributes(ref DependencyList dependencies, NodeFactory factory, EcmaModule module, CustomAttributeHandleCollection attributeHandles, TypeSystemEntity parent)
vitek-karas marked this conversation as resolved.
Show resolved Hide resolved
{
MetadataReader reader = module.MetadataReader;
var mdManager = (UsageBasedMetadataManager)factory.MetadataManager;
Expand All @@ -126,7 +126,7 @@ private static void AddDependenciesDueToCustomAttributes(ref DependencyList depe
CustomAttributeValue<TypeDesc> decodedValue = attribute.DecodeValue(attributeTypeProvider);

// Make a new list in case we need to abort.
var caDependencies = factory.MetadataManager.GetDependenciesForCustomAttribute(factory, constructor, decodedValue) ?? new DependencyList();
var caDependencies = factory.MetadataManager.GetDependenciesForCustomAttribute(factory, constructor, decodedValue, parent) ?? new DependencyList();

caDependencies.Add(factory.ReflectableMethod(constructor), "Attribute constructor");
caDependencies.Add(factory.ConstructedTypeSymbol(constructor.OwningType), "Attribute type");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -854,7 +854,7 @@ public virtual void GetDependenciesDueToAccess(ref DependencyList dependencies,
{
}

public virtual DependencyList GetDependenciesForCustomAttribute(NodeFactory factory, MethodDesc attributeCtor, CustomAttributeValue decodedValue)
public virtual DependencyList GetDependenciesForCustomAttribute(NodeFactory factory, MethodDesc attributeCtor, CustomAttributeValue decodedValue, TypeSystemEntity parent)
{
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -702,12 +702,12 @@ public override void GetDependenciesDueToAccess(ref DependencyList dependencies,
}
}

public override DependencyList GetDependenciesForCustomAttribute(NodeFactory factory, MethodDesc attributeCtor, CustomAttributeValue decodedValue)
public override DependencyList GetDependenciesForCustomAttribute(NodeFactory factory, MethodDesc attributeCtor, CustomAttributeValue decodedValue, TypeSystemEntity parent)
{
bool scanReflection = (_generationOptions & UsageBasedMetadataGenerationOptions.ReflectionILScanning) != 0;
if (scanReflection)
{
return (new AttributeDataFlow(Logger, factory, FlowAnnotations, new Logging.MessageOrigin(attributeCtor))).ProcessAttributeDataflow(attributeCtor, decodedValue);
return (new AttributeDataFlow(Logger, factory, FlowAnnotations, new Logging.MessageOrigin(parent))).ProcessAttributeDataflow(attributeCtor, decodedValue);
}

return null;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright (c) .NET Foundation and contributors. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

using System;

namespace Mono.Linker.Tests.Cases.Expectations.Assertions
{
[AttributeUsage (AttributeTargets.Class)]
public sealed class KeptPrivateImplementationDetailsAttribute : KeptAttribute
{
public KeptPrivateImplementationDetailsAttribute (string methodName)
{
if (string.IsNullOrEmpty (methodName))
throw new ArgumentException ("Value cannot be null or empty.", nameof (methodName));
}
}
}
Loading