Skip to content

Complete warnings for AOT unsafe interop #74697

Open
@jkotas

Description

@jkotas

Warnings for AOT unsafe interop are incomplete best effort currently: #74630 (comment)

  • Generate warnings for unsafe interop in marshalled structs
  • Generate warnings for AOT unsafe marshallers like AsAny and LayoutClass
  • Use actual marshaller kind to produce the warning instead of the approximation at
    static bool IsComInterop(MarshalAsDescriptor? marshalInfoProvider, TypeDesc parameterType)
    {
    // This is best effort. One can likely find ways how to get COM without triggering these alarms.
    // AsAny marshalling of a struct with an object-typed field would be one, for example.
    // This logic roughly corresponds to MarshalInfo::MarshalInfo in CoreCLR,
    // not trying to handle invalid cases and distinctions that are not interesting wrt
    // "is this COM?" question.
    NativeTypeKind nativeType = NativeTypeKind.Default;
    if (marshalInfoProvider != null)
    {
    nativeType = marshalInfoProvider.Type;
    }
    if (nativeType == NativeTypeKind.IUnknown || nativeType == NativeTypeKind.IDispatch || nativeType == NativeTypeKind.Intf)
    {
    // This is COM by definition
    return true;
    }
    if (nativeType == NativeTypeKind.Default)
    {
    TypeSystemContext context = parameterType.Context;
    if (parameterType.IsPointer)
    return false;
    while (parameterType.IsParameterizedType)
    parameterType = ((ParameterizedType)parameterType).ParameterType;
    if (parameterType.IsWellKnownType(Internal.TypeSystem.WellKnownType.Array))
    {
    // System.Array marshals as IUnknown by default
    return true;
    }
    else if (parameterType.IsWellKnownType(Internal.TypeSystem.WellKnownType.String) ||
    InteropTypes.IsStringBuilder(context, parameterType))
    {
    // String and StringBuilder are special cased by interop
    return false;
    }
    if (parameterType.IsValueType)
    {
    // Value types don't marshal as COM
    return false;
    }
    else if (parameterType.IsInterface)
    {
    // Interface types marshal as COM by default
    return true;
    }
    else if (parameterType.IsDelegate || parameterType.IsWellKnownType(Internal.TypeSystem.WellKnownType.MulticastDelegate)
    || parameterType == context.GetWellKnownType(Internal.TypeSystem.WellKnownType.MulticastDelegate).BaseType)
    {
    // Delegates are special cased by interop
    return false;
    }
    else if (InteropTypes.IsCriticalHandle(context, parameterType))
    {
    // Subclasses of CriticalHandle are special cased by interop
    return false;
    }
    else if (InteropTypes.IsSafeHandle(context, parameterType))
    {
    // Subclasses of SafeHandle are special cased by interop
    return false;
    }
    else if (parameterType is MetadataType mdType && !mdType.IsSequentialLayout && !mdType.IsExplicitLayout)
    {
    // Rest of classes that don't have layout marshal as COM
    return true;
    }
    }
    return false;
    }
  • Steer people towards P/Invoke source generator by the warning text

Metadata

Metadata

Assignees

No one assigned

    Labels

    EpicGroups multiple user stories. Can be grouped under a theme.area-NativeAOT-coreclr

    Type

    No type

    Projects

    Status

    No status

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions