提交 d4a181fa 编写于 作者: A Andy Gocke

Fix loading the type of FixedBufferAttribute in fields

The current code attempts to load an arbitrary type from the
FixedBufferAttribute, which represents the type of pointer which
is returned by the fixed buffer field in an unsafe struct. This is
a problem because it is not done with assembly identity unification
and the unification may depend on the current compilation, even though
the type is in metadata.

However, the type of the fixed buffer field is limited to SpecialTypes,
so rather than trying to do unification we can simply load the special
type of the field directly.

Fixes #2385
上级 6039dd9b
......@@ -239,11 +239,13 @@ private bool IsFixedBuffer(out int fixedSize, out TypeSymbol fixedElementType)
if (containingPEModule.Module.HasFixedBufferAttribute(_handle, out elementTypeName, out bufferSize))
{
var decoder = new MetadataDecoder(containingPEModule);
var elementType = decoder.GetTypeSymbolForSerializedType(elementTypeName);
if (elementType.FixedBufferElementSizeInBytes() != 0)
var specialTypeName = MetadataHelpers.DecodeTypeName(elementTypeName).TopLevelType;
var specialType = SpecialTypes.GetTypeFromMetadataName(specialTypeName);
if (specialType != SpecialType.None &&
specialType.FixedBufferElementSizeInBytes() != 0)
{
fixedSize = bufferSize;
fixedElementType = elementType;
fixedElementType = decoder.GetSpecialType(specialType);
return true;
}
}
......
......@@ -36,6 +36,54 @@ private static string GetEscapedNewLine()
#region Unsafe regions
[Fact]
public void FixedSizeBuffer()
{
var text1 = @"
using System;
using System.Runtime.InteropServices;
public static class R
{
public unsafe struct S
{
public fixed byte Buffer[16];
}
}";
var comp1 = CreateCompilation(text1, assemblyName: "assembly1", references: new[] { MscorlibRef_v20 },
options: TestOptions.UnsafeDebugDll);
var ref1 = comp1.EmitToImageReference();
var text2 = @"
using System;
class C
{
unsafe void M(byte* p)
{
R.S* p2 = (R.S*)p;
IntPtr p3 = M2((IntPtr)p2[0].Buffer);
}
unsafe IntPtr M2(IntPtr p) => p;
}";
var comp2 = CreateCompilationWithMscorlib45(text2,
references: new[] { ref1 },
options: TestOptions.UnsafeDebugDll);
comp2.VerifyDiagnostics(
// warning CS1701: Assuming assembly reference 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' used by 'assembly1' matches identity 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' of 'mscorlib', you may need to supply runtime policy
Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "assembly1", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "mscorlib").WithLocation(1, 1),
// warning CS1701: Assuming assembly reference 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' used by 'assembly1' matches identity 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' of 'mscorlib', you may need to supply runtime policy
Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "assembly1", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "mscorlib").WithLocation(1, 1),
// warning CS1701: Assuming assembly reference 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' used by 'assembly1' matches identity 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' of 'mscorlib', you may need to supply runtime policy
Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "assembly1", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "mscorlib").WithLocation(1, 1),
// warning CS1701: Assuming assembly reference 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' used by 'assembly1' matches identity 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' of 'mscorlib', you may need to supply runtime policy
Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "assembly1", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "mscorlib").WithLocation(1, 1),
// warning CS1701: Assuming assembly reference 'mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' used by 'assembly1' matches identity 'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' of 'mscorlib', you may need to supply runtime policy
Diagnostic(ErrorCode.WRN_UnifyReferenceMajMin).WithArguments("mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "assembly1", "mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089", "mscorlib").WithLocation(1, 1));
}
[Fact]
public void CompilationNotUnsafe1()
{
......
......@@ -70,7 +70,7 @@ protected TypeSymbol MakePointerTypeSymbol(TypeSymbol type, ImmutableArray<Modif
return _factory.MakePointerTypeSymbol(this.moduleSymbol, type, customModifiers);
}
protected TypeSymbol GetSpecialType(SpecialType specialType)
internal TypeSymbol GetSpecialType(SpecialType specialType)
{
return _factory.GetSpecialType(this.moduleSymbol, specialType);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册