Skip to content

Commit 2bbf291

Browse files
authored
Avoid an infinite cycle in MakeAcyclicBaseType (#81005)
Fixes #80987
1 parent 8559c14 commit 2bbf291

File tree

3 files changed

+244
-1
lines changed

3 files changed

+244
-1
lines changed

src/Compilers/CSharp/Portable/Symbols/Source/SourceNamedTypeSymbol_Bases.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -719,10 +719,13 @@ private NamedTypeSymbol MakeAcyclicBaseType(BindingDiagnosticBag diagnostics)
719719
var typeKind = this.TypeKind;
720720
var compilation = this.DeclaringCompilation;
721721
NamedTypeSymbol declaredBase;
722+
bool reportAtFirstLocation = false;
723+
722724
if (typeKind == TypeKind.Enum)
723725
{
724726
Debug.Assert((object)GetDeclaredBaseType(basesBeingResolved: null) == null, "Computation skipped for enums");
725727
declaredBase = compilation.GetSpecialType(SpecialType.System_Enum);
728+
reportAtFirstLocation = true;
726729
}
727730
else if (typeKind == TypeKind.Extension)
728731
{
@@ -745,17 +748,20 @@ private NamedTypeSymbol MakeAcyclicBaseType(BindingDiagnosticBag diagnostics)
745748
}
746749

747750
declaredBase = compilation.GetSpecialType(SpecialType.System_Object);
751+
reportAtFirstLocation = true;
748752
break;
749753

750754
case TypeKind.Struct:
751755
declaredBase = compilation.GetSpecialType(SpecialType.System_ValueType);
756+
reportAtFirstLocation = true;
752757
break;
753758

754759
case TypeKind.Interface:
755760
return null;
756761

757762
case TypeKind.Delegate:
758763
declaredBase = compilation.GetSpecialType(SpecialType.System_MulticastDelegate);
764+
reportAtFirstLocation = true;
759765
break;
760766

761767
default:
@@ -786,7 +792,7 @@ private NamedTypeSymbol MakeAcyclicBaseType(BindingDiagnosticBag diagnostics)
786792
}
787793
while ((object)current != null);
788794

789-
diagnostics.Add(useSiteInfo.Diagnostics.IsNullOrEmpty() ? Location.None : (FindBaseRefSyntax(declaredBase) ?? GetFirstLocation()), useSiteInfo);
795+
diagnostics.Add(useSiteInfo.Diagnostics.IsNullOrEmpty() ? Location.None : ((reportAtFirstLocation ? null : FindBaseRefSyntax(declaredBase)) ?? GetFirstLocation()), useSiteInfo);
790796

791797
return declaredBase;
792798
}

src/Compilers/CSharp/Test/Semantic/Semantics/BindingTests.cs

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4273,5 +4273,132 @@ void M(object obj) { }
42734273
// M<int>(default!);
42744274
Diagnostic(ErrorCode.ERR_BadArity, "M<int>").WithArguments("Program.M<T1, T2>(T1)", "method", "2").WithLocation(5, 9));
42754275
}
4276+
4277+
[Fact]
4278+
[WorkItem("https://github.com/dotnet/roslyn/issues/80987")]
4279+
public void MissingCoreReference_01()
4280+
{
4281+
var source =
4282+
@"
4283+
namespace Magic
4284+
{
4285+
public enum Cookie : UInt32;
4286+
}
4287+
";
4288+
var comp = CreateEmptyCompilation(source);
4289+
comp.VerifyDiagnostics(
4290+
// (4,17): error CS0518: Predefined type 'System.Enum' is not defined or imported
4291+
// public enum Cookie : UInt32;
4292+
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "Cookie").WithArguments("System.Enum").WithLocation(4, 17),
4293+
// (4,26): error CS0518: Predefined type 'System.Enum' is not defined or imported
4294+
// public enum Cookie : UInt32;
4295+
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "UInt32").WithArguments("System.Enum").WithLocation(4, 26),
4296+
// (4,26): error CS0518: Predefined type 'System.Object' is not defined or imported
4297+
// public enum Cookie : UInt32;
4298+
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "UInt32").WithArguments("System.Object").WithLocation(4, 26),
4299+
// (4,26): error CS0246: The type or namespace name 'UInt32' could not be found (are you missing a using directive or an assembly reference?)
4300+
// public enum Cookie : UInt32;
4301+
Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "UInt32").WithArguments("UInt32").WithLocation(4, 26),
4302+
// (4,26): error CS1008: Type byte, sbyte, short, ushort, int, uint, long, or ulong expected
4303+
// public enum Cookie : UInt32;
4304+
Diagnostic(ErrorCode.ERR_IntegralTypeExpected, "UInt32").WithLocation(4, 26)
4305+
);
4306+
}
4307+
4308+
[Fact]
4309+
[WorkItem("https://github.com/dotnet/roslyn/issues/80987")]
4310+
public void MissingCoreReference_02()
4311+
{
4312+
var source =
4313+
@"
4314+
namespace Magic
4315+
{
4316+
public enum Cookie : int;
4317+
}
4318+
";
4319+
var comp = CreateEmptyCompilation(source);
4320+
comp.VerifyDiagnostics(
4321+
// (4,17): error CS0518: Predefined type 'System.Enum' is not defined or imported
4322+
// public enum Cookie : int;
4323+
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "Cookie").WithArguments("System.Enum").WithLocation(4, 17),
4324+
// (4,26): error CS0518: Predefined type 'System.Int32' is not defined or imported
4325+
// public enum Cookie : int;
4326+
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "int").WithArguments("System.Int32").WithLocation(4, 26)
4327+
);
4328+
}
4329+
4330+
[Fact]
4331+
[WorkItem("https://github.com/dotnet/roslyn/issues/80987")]
4332+
public void MissingCoreReference_03()
4333+
{
4334+
var source =
4335+
@"
4336+
namespace Magic
4337+
{
4338+
public class Cookie : UInt32;
4339+
}
4340+
";
4341+
var comp = CreateEmptyCompilation(source);
4342+
comp.VerifyDiagnostics(
4343+
// (4,27): error CS0246: The type or namespace name 'UInt32' could not be found (are you missing a using directive or an assembly reference?)
4344+
// public class Cookie : UInt32;
4345+
Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "UInt32").WithArguments("UInt32").WithLocation(4, 27)
4346+
);
4347+
}
4348+
4349+
[Fact]
4350+
[WorkItem("https://github.com/dotnet/roslyn/issues/80987")]
4351+
public void MissingCoreReference_04()
4352+
{
4353+
var source =
4354+
@"
4355+
namespace Magic
4356+
{
4357+
public struct Cookie : UInt32;
4358+
}
4359+
";
4360+
var comp = CreateEmptyCompilation(source);
4361+
comp.VerifyDiagnostics(
4362+
// (4,19): error CS0518: Predefined type 'System.ValueType' is not defined or imported
4363+
// public struct Cookie : UInt32;
4364+
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "Cookie").WithArguments("System.ValueType").WithLocation(4, 19),
4365+
// (4,28): error CS0246: The type or namespace name 'UInt32' could not be found (are you missing a using directive or an assembly reference?)
4366+
// public struct Cookie : UInt32;
4367+
Diagnostic(ErrorCode.ERR_SingleTypeNameNotFound, "UInt32").WithArguments("UInt32").WithLocation(4, 28)
4368+
);
4369+
}
4370+
4371+
[Fact]
4372+
[WorkItem("https://github.com/dotnet/roslyn/issues/80987")]
4373+
public void MissingCoreReference_05()
4374+
{
4375+
var source =
4376+
@"
4377+
static class Ext
4378+
{
4379+
extension(Ext)
4380+
{
4381+
}
4382+
}
4383+
";
4384+
var comp = CreateEmptyCompilation(source);
4385+
comp.VerifyDiagnostics(
4386+
// (2,14): error CS0518: Predefined type 'System.Object' is not defined or imported
4387+
// static class Ext
4388+
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "Ext").WithArguments("System.Object").WithLocation(2, 14),
4389+
// (4,5): error CS0518: Predefined type 'System.Object' is not defined or imported
4390+
// extension(Ext)
4391+
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "extension").WithArguments("System.Object").WithLocation(4, 5),
4392+
// (4,5): error CS1110: Cannot define a new extension because the compiler required type 'System.Runtime.CompilerServices.ExtensionAttribute' cannot be found. Are you missing a reference to System.Core.dll?
4393+
// extension(Ext)
4394+
Diagnostic(ErrorCode.ERR_ExtensionAttrNotFound, "extension").WithArguments("System.Runtime.CompilerServices.ExtensionAttribute").WithLocation(4, 5),
4395+
// (4,14): error CS0518: Predefined type 'System.Void' is not defined or imported
4396+
// extension(Ext)
4397+
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "(").WithArguments("System.Void").WithLocation(4, 14),
4398+
// (4,15): error CS0518: Predefined type 'System.Object' is not defined or imported
4399+
// extension(Ext)
4400+
Diagnostic(ErrorCode.ERR_PredefinedTypeNotFound, "Ext").WithArguments("System.Object").WithLocation(4, 15)
4401+
);
4402+
}
42764403
}
42774404
}

src/Compilers/VisualBasic/Test/Semantic/Binding/BindingErrorTests.vb

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26195,5 +26195,115 @@ BC30456: 'ExtensionMethodNotFound2' is not a member of 'String'.
2619526195
</expected>)
2619626196
End Sub
2619726197

26198+
<Fact(), WorkItem("https://github.com/dotnet/roslyn/issues/80987")>
26199+
Public Sub MissingCoreReference_01()
26200+
Dim source =
26201+
<compilation name="Lib">
26202+
<file name="a.vb"><![CDATA[
26203+
Enum E As UInt32
26204+
X
26205+
End Enum
26206+
]]></file>
26207+
</compilation>
26208+
26209+
Dim compilation = CreateEmptyCompilation(source)
26210+
26211+
compilation.AssertTheseDiagnostics(
26212+
<expected>
26213+
BC30002: Type 'System.Void' is not defined.
26214+
Enum E As UInt32
26215+
~~~~~~~~~~~~~~~~~
26216+
BC30002: Type 'System.Int32' is not defined.
26217+
Enum E As UInt32
26218+
~
26219+
BC31091: Import of type '[Enum]' from assembly or module 'Lib.dll' failed.
26220+
Enum E As UInt32
26221+
~
26222+
BC30002: Type 'UInt32' is not defined.
26223+
Enum E As UInt32
26224+
~~~~~~
26225+
BC30650: Enums must be declared as an integral type.
26226+
Enum E As UInt32
26227+
~~~~~~
26228+
BC31091: Import of type '[Enum]' from assembly or module 'Lib.dll' failed.
26229+
Enum E As UInt32
26230+
~~~~~~
26231+
</expected>)
26232+
End Sub
26233+
26234+
<Fact(), WorkItem("https://github.com/dotnet/roslyn/issues/80987")>
26235+
Public Sub MissingCoreReference_02()
26236+
Dim source =
26237+
<compilation name="Lib">
26238+
<file name="a.vb"><![CDATA[
26239+
Enum E As Integer
26240+
X
26241+
End Enum
26242+
]]></file>
26243+
</compilation>
26244+
26245+
Dim compilation = CreateEmptyCompilation(source)
26246+
26247+
compilation.AssertTheseDiagnostics(
26248+
<expected>
26249+
BC30002: Type 'System.Void' is not defined.
26250+
Enum E As Integer
26251+
~~~~~~~~~~~~~~~~~~
26252+
BC31091: Import of type '[Enum]' from assembly or module 'Lib.dll' failed.
26253+
Enum E As Integer
26254+
~
26255+
BC30002: Type 'System.Int32' is not defined.
26256+
Enum E As Integer
26257+
~~~~~~~
26258+
</expected>)
26259+
End Sub
26260+
26261+
<Fact(), WorkItem("https://github.com/dotnet/roslyn/issues/80987")>
26262+
Public Sub MissingCoreReference_03()
26263+
Dim source =
26264+
<compilation name="Lib">
26265+
<file name="a.vb"><![CDATA[
26266+
Class C
26267+
Inherits UInt32
26268+
End Class
26269+
]]></file>
26270+
</compilation>
26271+
26272+
Dim compilation = CreateEmptyCompilation(source)
26273+
26274+
compilation.AssertTheseDiagnostics(
26275+
<expected>
26276+
BC30002: Type 'System.Void' is not defined.
26277+
Class C
26278+
~~~~~~~~
26279+
BC30002: Type 'UInt32' is not defined.
26280+
Inherits UInt32
26281+
~~~~~~
26282+
</expected>)
26283+
End Sub
26284+
26285+
<Fact(), WorkItem("https://github.com/dotnet/roslyn/issues/80987")>
26286+
Public Sub MissingCoreReference_04()
26287+
Dim source =
26288+
<compilation name="Lib">
26289+
<file name="a.vb"><![CDATA[
26290+
Class C
26291+
End Class
26292+
]]></file>
26293+
</compilation>
26294+
26295+
Dim compilation = CreateEmptyCompilation(source)
26296+
26297+
compilation.AssertTheseDiagnostics(
26298+
<expected>
26299+
BC30002: Type 'System.Void' is not defined.
26300+
Class C
26301+
~~~~~~~~
26302+
BC31091: Import of type 'Object' from assembly or module 'Lib.dll' failed.
26303+
Class C
26304+
~
26305+
</expected>)
26306+
End Sub
26307+
2619826308
End Class
2619926309
End Namespace

0 commit comments

Comments
 (0)