Browse Source

Fix #2921: struct type definition contains duplicate default constructor.

pull/2953/head
Siegfried Pammer 2 years ago
parent
commit
8b0c7fbe85
  1. 10
      ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs
  2. 5
      ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemTestCase.cs
  3. 12
      ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs

10
ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemLoaderTests.cs

@ -616,6 +616,16 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
Assert.IsTrue(ctors.All(c => c.Accessibility == Accessibility.Public)); Assert.IsTrue(ctors.All(c => c.Accessibility == Accessibility.Public));
} }
[Test]
public void NoDefaultConstructorAddedToStruct()
{
var ctors = compilation.FindType(typeof(MyStructWithDefaultCtor)).GetConstructors();
Assert.AreEqual(1, ctors.Count());
Assert.IsFalse(ctors.Any(c => c.IsStatic));
Assert.IsTrue(ctors.All(c => c.ReturnType.Kind == TypeKind.Void));
Assert.IsTrue(ctors.All(c => c.Accessibility == Accessibility.Public));
}
[Test] [Test]
public void NoDefaultConstructorAddedToClass() public void NoDefaultConstructorAddedToClass()
{ {

5
ICSharpCode.Decompiler.Tests/TypeSystem/TypeSystemTestCase.cs

@ -140,6 +140,11 @@ namespace ICSharpCode.Decompiler.Tests.TypeSystem
public MyStructWithCtor(int a) { } public MyStructWithCtor(int a) { }
} }
public struct MyStructWithDefaultCtor
{
public MyStructWithDefaultCtor() { }
}
public class MyClassWithCtor public class MyClassWithCtor
{ {
private MyClassWithCtor(int a) { } private MyClassWithCtor(int a) { }

12
ICSharpCode.Decompiler/TypeSystem/Implementation/MetadataTypeDefinition.cs

@ -259,17 +259,23 @@ namespace ICSharpCode.Decompiler.TypeSystem.Implementation
var methodsCollection = metadata.GetTypeDefinition(handle).GetMethods(); var methodsCollection = metadata.GetTypeDefinition(handle).GetMethods();
var methodsList = new List<IMethod>(methodsCollection.Count); var methodsList = new List<IMethod>(methodsCollection.Count);
var methodSemantics = module.PEFile.MethodSemanticsLookup; var methodSemantics = module.PEFile.MethodSemanticsLookup;
bool hasDefaultCtor = false;
foreach (MethodDefinitionHandle h in methodsCollection) foreach (MethodDefinitionHandle h in methodsCollection)
{ {
var md = metadata.GetMethodDefinition(h); var md = metadata.GetMethodDefinition(h);
if (methodSemantics.GetSemantics(h).Item2 == 0 && module.IsVisible(md.Attributes)) if (methodSemantics.GetSemantics(h).Item2 == 0 && module.IsVisible(md.Attributes))
{ {
methodsList.Add(module.GetDefinition(h)); IMethod method = module.GetDefinition(h);
if (method.SymbolKind == SymbolKind.Constructor && !method.IsStatic && method.Parameters.Count == 0)
{
hasDefaultCtor = true;
}
methodsList.Add(method);
} }
} }
if (this.Kind == TypeKind.Struct || this.Kind == TypeKind.Enum) if (!hasDefaultCtor && (this.Kind == TypeKind.Struct || this.Kind == TypeKind.Enum))
{ {
methodsList.Add(FakeMethod.CreateDummyConstructor(Compilation, this, IsAbstract ? Accessibility.Protected : Accessibility.Public)); methodsList.Add(FakeMethod.CreateDummyConstructor(Compilation, this, Accessibility.Public));
} }
if ((module.TypeSystemOptions & TypeSystemOptions.Uncached) != 0) if ((module.TypeSystemOptions & TypeSystemOptions.Uncached) != 0)
return methodsList; return methodsList;

Loading…
Cancel
Save