提交 397e7d7a 编写于 作者: V vsadov

Not poisoning restricted types known to be stack only.

TypedReference
ArgIterator
RuntimeArgumentHandle

Fixes:#https://github.com/dotnet/roslyn/issues/22198
上级 f827f7a8
......@@ -1131,7 +1131,7 @@ internal override void AddSynthesizedAttributes(PEModuleBuilder moduleBuilder, r
// we will not emit Obsolete even if Deprecated or Experimental was used.
// we do not want to get into a scenario where different kinds of deprecation are combined together.
//
if (obsoleteData == null)
if (obsoleteData == null && !this.IsRestrictedType(ignoreSpanLikeTypes:true))
{
AddSynthesizedAttribute(ref attributes, compilation.TrySynthesizeAttribute(WellKnownMember.System_ObsoleteAttribute__ctor,
ImmutableArray.Create(
......
......@@ -941,19 +941,99 @@ void Method()
);
}
private static void AssertReferencedIsByRefLikeAttributes(Accessibility accessibility, ImmutableArray<CSharpAttributeData> attributes, string assemblyName)
[WorkItem(22198, "https://github.com/dotnet/roslyn/issues/22198")]
[Fact]
public void SpecialTypes_CorLib()
{
Assert.Equal(2, attributes.Count());
var source1 =
@"
namespace System
{
public class Object { }
public class String { }
public struct Void { }
public class ValueType { }
public struct Int32 { }
public struct Boolean { }
public struct Decimal { }
public class Attribute{ }
public class ObsoleteAttribute: Attribute
{
public ObsoleteAttribute(string message, bool error){}
}
public ref struct TypedReference { }
public ref struct ArgIterator { }
public ref struct RuntimeArgumentHandle { }
public ref struct NotTypedReference { }
}";
var compilation1 = CreateCompilation(source1, assemblyName: GetUniqueName());
CompileAndVerify(compilation1, verify: false, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("System.TypedReference");
Assert.True(type.IsByRefLikeType);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name, hasObsolete: false);
type = module.ContainingAssembly.GetTypeByMetadataName("System.ArgIterator");
Assert.True(type.IsByRefLikeType);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name, hasObsolete: false);
type = module.ContainingAssembly.GetTypeByMetadataName("System.RuntimeArgumentHandle");
Assert.True(type.IsByRefLikeType);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name, hasObsolete: false);
type = module.ContainingAssembly.GetTypeByMetadataName("System.NotTypedReference");
Assert.True(type.IsByRefLikeType);
// control case. Not a special type.
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name, hasObsolete: true);
});
}
[Fact]
public void SpecialTypes_NotCorLib()
{
var text = @"
namespace System
{
public ref struct TypedReference { }
}
";
CompileAndVerify(text, verify: false, symbolValidator: module =>
{
var type = module.ContainingAssembly.GetTypeByMetadataName("System.TypedReference");
Assert.True(type.IsByRefLikeType);
AssertReferencedIsByRefLikeAttributes(Accessibility.Internal, type.GetAttributes(), module.ContainingAssembly.Name);
});
}
private static void AssertReferencedIsByRefLikeAttributes(
Accessibility accessibility,
ImmutableArray<CSharpAttributeData> attributes,
string assemblyName,
bool hasObsolete = true)
{
Assert.Equal(hasObsolete? 2: 1, attributes.Count());
var attributeType = attributes[0].AttributeClass;
Assert.Equal("System.Runtime.CompilerServices.IsByRefLikeAttribute", attributeType.ToDisplayString());
Assert.Equal(assemblyName, attributeType.ContainingAssembly.Name);
Assert.Equal(accessibility, attributeType.DeclaredAccessibility);
var attribute = attributes[1];
Assert.Equal("System.ObsoleteAttribute", attribute.AttributeClass.ToDisplayString());
Assert.Equal("Types with embedded references are not supported in this version of your compiler.", attribute.ConstructorArguments.ElementAt(0).Value);
Assert.Equal(false, attribute.ConstructorArguments.ElementAt(1).Value);
if (hasObsolete)
{
var attribute = attributes[1];
Assert.Equal("System.ObsoleteAttribute", attribute.AttributeClass.ToDisplayString());
Assert.Equal("Types with embedded references are not supported in this version of your compiler.", attribute.ConstructorArguments.ElementAt(0).Value);
Assert.Equal(false, attribute.ConstructorArguments.ElementAt(1).Value);
}
}
private static void AssertNotReferencedIsByRefLikeAttribute(ImmutableArray<CSharpAttributeData> attributes)
......
......@@ -373,6 +373,56 @@ public static T Read<T>() where T : new()
);
}
[Fact()]
public void NoTypedRefBox2()
{
var source1 =
@"namespace System
{
public class Object { }
public class String { }
public struct Void { }
public class ValueType { }
public struct Int32 { }
public struct Boolean { }
public struct Decimal { }
public class Attribute{ }
public class ObsoleteAttribute: Attribute
{
public ObsoleteAttribute(string message, bool error){}
}
public ref struct TypedReference { }
}";
var compilation1 = CreateCompilation(source1, assemblyName: GetUniqueName());
var reference1 = MetadataReference.CreateFromStream(compilation1.EmitToStream());
var source2 =
@"
public class C1
{
public static object rrr;
public static T Read<T>() where T : new()
{
T result = new T();
var refresult = __makeref(result);
rrr = refresult;
rrr = (object)__makeref(result);
return result;
}
}
";
var compilation2 = CreateCompilation(source2, new[] { reference1 });
compilation2.VerifyDiagnostics(
// (10,15): error CS0029: Cannot implicitly convert type 'System.TypedReference' to 'object'
// rrr = refresult;
Diagnostic(ErrorCode.ERR_NoImplicitConv, "refresult").WithArguments("System.TypedReference", "object").WithLocation(10, 15),
// (11,15): error CS0030: Cannot convert type 'System.TypedReference' to 'object'
// rrr = (object)__makeref(result);
Diagnostic(ErrorCode.ERR_NoExplicitConv, "(object)__makeref(result)").WithArguments("System.TypedReference", "object").WithLocation(11, 15)
);
}
[WorkItem(530861, "http://vstfdevdiv:8080/DevDiv2/DevDiv/_workitems/edit/530861")]
[Fact]
public void MissingStringLengthForEach()
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册