Browse Source

Fixed a crash when a C++ ctor indirectly calls a virtual function on the object being constructed.

Signed-off-by: Dimitar Dobrev <dpldobrev@yahoo.com>
pull/566/head
Dimitar Dobrev 10 years ago
parent
commit
bb59ca17fb
  1. 11
      src/Generator/Generators/CSharp/CSharpTextTemplate.cs
  2. 9
      tests/CSharp/CSharp.Tests.cs
  3. 25
      tests/CSharp/CSharp.cpp
  4. 22
      tests/CSharp/CSharp.h

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

@ -1321,19 +1321,14 @@ namespace CppSharp.Generators.CSharp @@ -1321,19 +1321,14 @@ namespace CppSharp.Generators.CSharp
WriteLine("void SetupVTables()");
WriteStartBraceIndent();
WriteLine("if (NativeToManagedMap.ContainsKey({0}))", Helpers.InstanceIdentifier);
WriteLine("if (__OriginalVTables != null)");
WriteLineIndent("return;");
WriteLine("var native = (Internal*) {0}.ToPointer();", Helpers.InstanceIdentifier);
NewLine();
// Save the original vftable pointers.
WriteLine("if (__OriginalVTables == null)");
WriteStartBraceIndent();
SaveOriginalVTablePointers(@class.Layout.VFTables);
WriteCloseBraceIndent();
NewLine();
// Get the _Thunks
@ -1605,6 +1600,8 @@ namespace CppSharp.Generators.CSharp @@ -1605,6 +1600,8 @@ namespace CppSharp.Generators.CSharp
NewLine();
WriteLine("var {0} = ({1}) NativeToManagedMap[instance];", Helpers.TargetIdentifier, @class.Name);
WriteLine("if ({0}.{1})", Helpers.TargetIdentifier, Helpers.OwnsNativeInstanceIdentifier);
WriteLineIndent("{0}.SetupVTables();", Helpers.TargetIdentifier);
GenerateVTableManagedCall(method);
WriteCloseBraceIndent();
@ -2424,6 +2421,7 @@ namespace CppSharp.Generators.CSharp @@ -2424,6 +2421,7 @@ namespace CppSharp.Generators.CSharp
WriteLine("{0} = Marshal.AllocHGlobal({1});", Helpers.InstanceIdentifier,
@class.Layout.Size);
WriteLine("{0} = true;", Helpers.OwnsNativeInstanceIdentifier);
WriteLine("NativeToManagedMap[{0}] = this;", Helpers.InstanceIdentifier);
if (method.IsCopyConstructor)
{
@ -2440,7 +2438,6 @@ namespace CppSharp.Generators.CSharp @@ -2440,7 +2438,6 @@ namespace CppSharp.Generators.CSharp
}
GenerateVTableClassSetupCall(@class);
WriteLine("NativeToManagedMap[{0}] = this;", Helpers.InstanceIdentifier);
}
public void GenerateInternalFunctionCall(Function function,

9
tests/CSharp/CSharp.Tests.cs

@ -470,4 +470,13 @@ public class CSharpTests : GeneratorTestFixture @@ -470,4 +470,13 @@ public class CSharpTests : GeneratorTestFixture
Assert.That(overridePropertyFromIndirectPrimaryBase.Property, Is.EqualTo(5));
}
}
[Test]
public void TestCallingVirtualBeforeCtorFinished()
{
using (new QApplication())
{
new QWidget();
}
}
}

25
tests/CSharp/CSharp.cpp

@ -833,3 +833,28 @@ int OverridePropertyFromIndirectPrimaryBase::property() @@ -833,3 +833,28 @@ int OverridePropertyFromIndirectPrimaryBase::property()
{
return 5;
}
QObject::QObject()
{
}
QObject::~QObject()
{
}
QWidget::QWidget()
{
QApplication::instance->notify(this);
}
QApplication::QApplication()
{
instance = this;
}
QApplication* QApplication::instance = 0;
void QApplication::notify(QObject* receiver)
{
delete receiver;
}

22
tests/CSharp/CSharp.h

@ -764,3 +764,25 @@ public: @@ -764,3 +764,25 @@ public:
OverridePropertyFromIndirectPrimaryBase();
int property();
};
class DLL_API QObject
{
public:
QObject();
virtual ~QObject();
};
class DLL_API QWidget : public QObject
{
public:
QWidget();
};
class DLL_API QApplication : public QObject
{
public:
QApplication();
static QApplication* instance;
virtual void notify(QObject* receiver);
};

Loading…
Cancel
Save