Browse Source

Revert "Fixed a crash when calling the dtor of an abstract type with MinGW."

This reverts commit 67e6e1204c.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/256/merge
Dimitar Dobrev 10 years ago
parent
commit
e4a40d0eed
  1. 107
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  2. 15
      tests/Common/Common.Tests.cs
  3. 8
      tests/Common/Common.cpp
  4. 8
      tests/Common/Common.h

107
src/Generator/Generators/CSharp/CSharpTextTemplate.cs

@ -512,11 +512,7 @@ namespace CppSharp.Generators.CSharp
method.SynthKind != FunctionSynthKind.AdjustedMethod) method.SynthKind != FunctionSynthKind.AdjustedMethod)
return; return;
if (method.IsProxy || if (method.IsProxy || (method.IsVirtual && !method.IsOperator))
(method.IsVirtual && !method.IsOperator &&
// virtual destructors in abstract classes may lack a pointer in the v-table
// so they have to be called by symbol and therefore not ignored
!(method.IsDestructor && @class.IsAbstract)))
return; return;
functions.Add(method); functions.Add(method);
@ -1394,7 +1390,7 @@ namespace CppSharp.Generators.CSharp
{ {
if (method.IsDestructor) if (method.IsDestructor)
{ {
WriteLine("{0}.DisposeImpl(false);", Helpers.TargetIdentifier); WriteLine("{0}.Dispose(false);", Helpers.TargetIdentifier);
return; return;
} }
@ -1702,13 +1698,7 @@ namespace CppSharp.Generators.CSharp
var dtor = @class.Destructors.FirstOrDefault(d => d.Access != AccessSpecifier.Private && d.IsVirtual); var dtor = @class.Destructors.FirstOrDefault(d => d.Access != AccessSpecifier.Private && d.IsVirtual);
var baseDtor = @class.BaseClass == null ? null : var baseDtor = @class.BaseClass == null ? null :
@class.BaseClass.Destructors.FirstOrDefault(d => !d.IsVirtual); @class.BaseClass.Destructors.FirstOrDefault(d => !d.IsVirtual);
if (ShouldGenerateClassNativeField(@class) || (dtor != null && baseDtor != null) || if (ShouldGenerateClassNativeField(@class) || (dtor != null && baseDtor != null))
// virtual destructors in abstract classes may lack a pointer in the v-table
// so they have to be called by symbol; thus we need an explicit Dispose override
@class.IsAbstract ||
// if the base type is abstract and the current type not,
// we need the regular v-table call so we have to override Dispose again
(!@class.IsAbstractImpl && @class.BaseClass != null && @class.BaseClass.IsAbstract))
GenerateDisposeMethods(@class); GenerateDisposeMethods(@class);
} }
} }
@ -1732,6 +1722,21 @@ namespace CppSharp.Generators.CSharp
{ {
var hasBaseClass = @class.HasBaseClass && @class.BaseClass.IsRefType; var hasBaseClass = @class.HasBaseClass && @class.BaseClass.IsRefType;
// Generate the IDispose Dispose() method.
if (!hasBaseClass)
{
PushBlock(CSharpBlockKind.Method);
WriteLine("public void Dispose()");
WriteStartBraceIndent();
WriteLine("Dispose(disposing: true);");
if (Options.GenerateFinalizers)
WriteLine("GC.SuppressFinalize(this);");
WriteCloseBraceIndent();
PopBlock(NewLineKind.BeforeNextBlock);
}
// Generate Dispose(bool) method // Generate Dispose(bool) method
PushBlock(CSharpBlockKind.Method); PushBlock(CSharpBlockKind.Method);
if (@class.IsValueType) if (@class.IsValueType)
@ -1746,43 +1751,6 @@ namespace CppSharp.Generators.CSharp
WriteLine("void Dispose(bool disposing)"); WriteLine("void Dispose(bool disposing)");
WriteStartBraceIndent(); WriteStartBraceIndent();
var dtor = @class.Destructors.FirstOrDefault();
if (dtor != null && dtor.Access != AccessSpecifier.Private &&
@class.HasNonTrivialDestructor && !dtor.IsPure)
{
NativeLibrary library;
if (!Options.CheckSymbols ||
Driver.Symbols.FindLibraryBySymbol(dtor.Mangled, out library))
{
if (dtor.IsVirtual && !@class.IsAbstract)
GenerateVirtualFunctionCall(dtor, @class, true);
else
GenerateInternalFunctionCall(dtor);
}
}
WriteCloseBraceIndent();
PopBlock(NewLineKind.BeforeNextBlock);
if (hasBaseClass) return;
// Generate the IDispose Dispose() method.
PushBlock(CSharpBlockKind.Method);
WriteLine("public void Dispose()");
WriteStartBraceIndent();
WriteLine("DisposeImpl(disposing: true);");
if (Options.GenerateFinalizers)
WriteLine("GC.SuppressFinalize(this);");
WriteCloseBraceIndent();
PopBlock(NewLineKind.BeforeNextBlock);
PushBlock(CSharpBlockKind.Method);
WriteLine("protected void DisposeImpl(bool disposing)");
WriteStartBraceIndent();
WriteLine("if (!{0} && disposing)", Helpers.OwnsNativeInstanceIdentifier); WriteLine("if (!{0} && disposing)", Helpers.OwnsNativeInstanceIdentifier);
WriteLineIndent("throw new global::System.InvalidOperationException" + WriteLineIndent("throw new global::System.InvalidOperationException" +
"(\"Managed instances owned by native code cannot be disposed of.\");"); "(\"Managed instances owned by native code cannot be disposed of.\");");
@ -1812,7 +1780,20 @@ namespace CppSharp.Generators.CSharp
} }
} }
WriteLine("Dispose(disposing: true);"); var dtor = @class.Destructors.FirstOrDefault();
if (dtor != null && dtor.Access != AccessSpecifier.Private &&
@class.HasNonTrivialDestructor && !dtor.IsPure)
{
NativeLibrary library;
if (!Options.CheckSymbols ||
Driver.Symbols.FindLibraryBySymbol(dtor.Mangled, out library))
{
if (dtor.IsVirtual)
GenerateVirtualFunctionCall(dtor, @class);
else
GenerateInternalFunctionCall(dtor);
}
}
WriteLine("if ({0})", Helpers.OwnsNativeInstanceIdentifier); WriteLine("if ({0})", Helpers.OwnsNativeInstanceIdentifier);
WriteLineIndent("Marshal.FreeHGlobal({0});", Helpers.InstanceIdentifier); WriteLineIndent("Marshal.FreeHGlobal({0});", Helpers.InstanceIdentifier);
@ -2252,11 +2233,14 @@ namespace CppSharp.Generators.CSharp
private static AccessSpecifier GetValidPropertyAccess(Property property) private static AccessSpecifier GetValidPropertyAccess(Property property)
{ {
if (property.Access == AccessSpecifier.Public) switch (property.Access)
return AccessSpecifier.Public; {
return property.IsOverride case AccessSpecifier.Public:
? ((Class) property.Namespace).GetBaseProperty(property).Access return AccessSpecifier.Public;
: property.Access; default:
return property.IsOverride ?
((Class) property.Namespace).GetBaseProperty(property).Access : property.Access;
}
} }
private void GenerateVirtualPropertyCall(Function method, Class @class, private void GenerateVirtualPropertyCall(Function method, Class @class,
@ -2266,8 +2250,7 @@ namespace CppSharp.Generators.CSharp
method.SynthKind != FunctionSynthKind.AbstractImplCall && method.SynthKind != FunctionSynthKind.AbstractImplCall &&
@class.HasNonAbstractBaseProperty(property)) @class.HasNonAbstractBaseProperty(property))
{ {
WriteLine(parameters == null ? WriteLine(parameters == null ? "return base.{0};" : "base.{0} = value;", property.Name);
"return base.{0};" : "base.{0} = value;", property.Name);
} }
else else
{ {
@ -2277,10 +2260,9 @@ namespace CppSharp.Generators.CSharp
} }
} }
private void GenerateVirtualFunctionCall(Method method, Class @class, private void GenerateVirtualFunctionCall(Method method, Class @class)
bool forceVirtualCall = false)
{ {
if (!forceVirtualCall && method.IsOverride && !method.IsPure && if (method.IsOverride && !method.IsPure &&
method.SynthKind != FunctionSynthKind.AbstractImplCall && method.SynthKind != FunctionSynthKind.AbstractImplCall &&
@class.HasNonAbstractBaseMethod(method)) @class.HasNonAbstractBaseMethod(method))
{ {
@ -2299,8 +2281,7 @@ namespace CppSharp.Generators.CSharp
{ {
var virtualCallBuilder = new StringBuilder(); var virtualCallBuilder = new StringBuilder();
var i = VTables.GetVTableIndex(function.OriginalFunction ?? function, @class); var i = VTables.GetVTableIndex(function.OriginalFunction ?? function, @class);
virtualCallBuilder.AppendFormat( virtualCallBuilder.AppendFormat("var {0} = *(void**) ((IntPtr) __OriginalVTables[0] + {1} * {2});",
"var {0} = *(void**) ((IntPtr) __OriginalVTables[0] + {1} * {2});",
Helpers.SlotIdentifier, i, Driver.TargetInfo.PointerWidth / 8); Helpers.SlotIdentifier, i, Driver.TargetInfo.PointerWidth / 8);
virtualCallBuilder.AppendLine(); virtualCallBuilder.AppendLine();

15
tests/Common/Common.Tests.cs

@ -555,20 +555,5 @@ public class CommonTests : GeneratorTestFixture
Assert.That(hasProblematicFields.c, Is.EqualTo('a')); Assert.That(hasProblematicFields.c, Is.EqualTo('a'));
} }
} }
[Test]
public void TestDisposingCustomDerivedFromVirtual()
{
using (new CustomDerivedFromVirtual())
{
}
}
private class CustomDerivedFromVirtual : AbstractWithVirtualDtor
{
public override void @abstract()
{
}
}
} }

8
tests/Common/Common.cpp

@ -555,11 +555,3 @@ int OverridesNonDirectVirtual::retInt()
{ {
return 3; return 3;
} }
AbstractWithVirtualDtor::AbstractWithVirtualDtor()
{
}
AbstractWithVirtualDtor::~AbstractWithVirtualDtor()
{
}

8
tests/Common/Common.h

@ -933,11 +933,3 @@ AbstractTemplate<T>::AbstractTemplate()
and therefore %HashBase pointers should never be used. and therefore %HashBase pointers should never be used.
*/ */
class DLL_API TestComments {}; class DLL_API TestComments {};
class DLL_API AbstractWithVirtualDtor
{
public:
AbstractWithVirtualDtor();
virtual ~AbstractWithVirtualDtor();
virtual void abstract() = 0;
};

Loading…
Cancel
Save