提交 f34d3e4d 编写于 作者: R Rikki Gibson

Fix unconditional binding of pointer types

上级 38650ea9
...@@ -79,12 +79,13 @@ private static void StructDependsClosure(NamedTypeSymbol type, HashSet<Symbol> p ...@@ -79,12 +79,13 @@ private static void StructDependsClosure(NamedTypeSymbol type, HashSet<Symbol> p
foreach (var member in type.GetMembersUnordered()) foreach (var member in type.GetMembersUnordered())
{ {
var field = member as FieldSymbol; var field = member as FieldSymbol;
if ((object)field == null || field.Type.TypeKind != TypeKind.Struct || field.IsStatic) var fieldType = field?.NonPointerType();
if (fieldType is null || fieldType.TypeKind != TypeKind.Struct || field.IsStatic)
{ {
continue; continue;
} }
StructDependsClosure((NamedTypeSymbol)field.Type, partialClosure, on); StructDependsClosure((NamedTypeSymbol)fieldType, partialClosure, on);
} }
} }
} }
...@@ -134,6 +135,12 @@ internal static ManagedKind GetManagedKind(NamedTypeSymbol type) ...@@ -134,6 +135,12 @@ internal static ManagedKind GetManagedKind(NamedTypeSymbol type)
} }
} }
// NOTE: If we do not check HasPointerType, we will unconditionally
// bind Type and that may cause infinite recursion.
// HasPointerType can use syntax directly and break recursion.
internal static TypeSymbol NonPointerType(this FieldSymbol field) =>
field.HasPointerType ? null : field.Type;
private static (bool definitelyManaged, bool hasGenerics) DependsOnDefinitelyManagedType(NamedTypeSymbol type, HashSet<Symbol> partialClosure) private static (bool definitelyManaged, bool hasGenerics) DependsOnDefinitelyManagedType(NamedTypeSymbol type, HashSet<Symbol> partialClosure)
{ {
Debug.Assert((object)type != null); Debug.Assert((object)type != null);
...@@ -164,16 +171,13 @@ private static (bool definitelyManaged, bool hasGenerics) DependsOnDefinitelyMan ...@@ -164,16 +171,13 @@ private static (bool definitelyManaged, bool hasGenerics) DependsOnDefinitelyMan
continue; continue;
} }
// pointers are unmanaged TypeSymbol fieldType = field.NonPointerType();
// NOTE: If we do not check HasPointerType, we will unconditionally if (fieldType is null)
// bind Type and that may cause infinite recursion.
// HasPointerType can use syntax directly and break recursion.
if (field.HasPointerType)
{ {
// pointers are unmanaged
continue; continue;
} }
TypeSymbol fieldType = field.Type;
NamedTypeSymbol fieldNamedType = fieldType as NamedTypeSymbol; NamedTypeSymbol fieldNamedType = fieldType as NamedTypeSymbol;
if ((object)fieldNamedType == null) if ((object)fieldNamedType == null)
{ {
......
...@@ -1889,7 +1889,7 @@ private bool HasStructCircularity(DiagnosticBag diagnostics) ...@@ -1889,7 +1889,7 @@ private bool HasStructCircularity(DiagnosticBag diagnostics)
{ {
continue; continue;
} }
var type = field.Type; var type = field.NonPointerType();
if (((object)type != null) && if (((object)type != null) &&
(type.TypeKind == TypeKind.Struct) && (type.TypeKind == TypeKind.Struct) &&
BaseTypeAnalysis.StructDependsOn((NamedTypeSymbol)type, this) && BaseTypeAnalysis.StructDependsOn((NamedTypeSymbol)type, this) &&
......
...@@ -9193,5 +9193,26 @@ void M(S s) ...@@ -9193,5 +9193,26 @@ void M(S s)
// int* f = &(s_f.Buf[0]); // int* f = &(s_f.Buf[0]);
Diagnostic(ErrorCode.ERR_FixedNeeded, "&(s_f.Buf[0])").WithLocation(17, 18)); Diagnostic(ErrorCode.ERR_FixedNeeded, "&(s_f.Buf[0])").WithLocation(17, 18));
} }
[Fact, WorkItem(34693, "https://github.com/dotnet/roslyn/issues/34693")]
public void Repro_34693()
{
var csharp = @"
namespace Interop
{
public unsafe struct PROPVARIANT
{
public CAPROPVARIANT ca;
}
public unsafe struct CAPROPVARIANT
{
public uint cElems;
public PROPVARIANT* pElems;
}
}";
var comp = CreateCompilation(csharp, options: TestOptions.UnsafeDebugDll);
comp.VerifyDiagnostics();
}
} }
} }
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册