From 2f170dc650542b40c5f1d3a923213c1d0b663b3f Mon Sep 17 00:00:00 2001 From: Dimitar Dobrev Date: Sat, 18 Sep 2021 23:14:03 +0300 Subject: [PATCH] Free returned by value instances, not object ones This was a dangerous bug by as the object remained in a deleted state to be used later. Signed-off-by: Dimitar Dobrev --- src/Generator/Generators/CSharp/CSharpMarshal.cs | 10 ++++++---- src/Generator/Generators/CSharp/CSharpSources.cs | 2 +- tests/Common/Common.Tests.cs | 3 +++ tests/Common/Common.cpp | 13 +++++++++++++ tests/Common/Common.h | 3 +++ 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/Generator/Generators/CSharp/CSharpMarshal.cs b/src/Generator/Generators/CSharp/CSharpMarshal.cs index 9f0e1ae03c..c0eff1cd55 100644 --- a/src/Generator/Generators/CSharp/CSharpMarshal.cs +++ b/src/Generator/Generators/CSharp/CSharpMarshal.cs @@ -300,14 +300,16 @@ public override bool VisitClassDecl(Class @class) if (Context.Context.ParserOptions.IsMicrosoftAbi) vtableIndex = @class.Layout.VFTables.IndexOf(@class.Layout.VFTables.First( v => v.Layout.Components.Any(c => c.Method == dtor))); + string instance = $"new {typePrinter.IntPtrType}(&{Context.ReturnVarName})"; Context.Before.WriteLine($@"var __vtables = new IntPtr[] {{ { string.Join(", ", originalClass.Layout.VTablePointers.Select( - x => $" * (IntPtr*) ({ Helpers.InstanceIdentifier} + {x.Offset})"))} }};"); - Context.Before.WriteLine($"var __slot = *(IntPtr*) (__vtables[{vtableIndex}] + {i} * sizeof(IntPtr));"); - Context.Before.Write($"Marshal.GetDelegateForFunctionPointer<{dtor.FunctionType}>(__slot)({Helpers.InstanceIdentifier}"); + x => $"*({typePrinter.IntPtrType}*) ({instance} + {x.Offset})"))} }};"); + Context.Before.WriteLine($@"var __slot = *({typePrinter.IntPtrType}*) (__vtables[{ + vtableIndex}] + {i} * sizeof({typePrinter.IntPtrType}));"); + Context.Before.Write($"Marshal.GetDelegateForFunctionPointer<{dtor.FunctionType}>(__slot)({instance}"); if (dtor.GatherInternalParams(Context.Context.ParserOptions.IsItaniumLikeAbi).Count > 1) { - Context.Before.WriteLine(", 0"); + Context.Before.Write(", 0"); } Context.Before.WriteLine(");"); } diff --git a/src/Generator/Generators/CSharp/CSharpSources.cs b/src/Generator/Generators/CSharp/CSharpSources.cs index 6315fc6aa2..e5dcf90bda 100644 --- a/src/Generator/Generators/CSharp/CSharpSources.cs +++ b/src/Generator/Generators/CSharp/CSharpSources.cs @@ -2689,7 +2689,7 @@ public void GenerateMethod(Method method, Class @class) } private bool GenerateMethodBody(Class @class, Method method, - QualifiedType returnType = default(QualifiedType)) + QualifiedType returnType = default) { var specialization = @class as ClassTemplateSpecialization; if (specialization != null) diff --git a/tests/Common/Common.Tests.cs b/tests/Common/Common.Tests.cs index 08a464fe02..67ee7d0333 100644 --- a/tests/Common/Common.Tests.cs +++ b/tests/Common/Common.Tests.cs @@ -52,6 +52,9 @@ public unsafe void TestCodeGeneration() { hasPropertyNamedAsParent.hasPropertyNamedAsParent.GetHashCode(); } + using (Common.FreeFunctionReturnsVirtualDtor) + { + } EnumWithUnderscores.lOWER_BEFORE_CAPITAL.GetHashCode(); EnumWithUnderscores.UnderscoreAtEnd.GetHashCode(); EnumWithUnderscores.CAPITALS_More.GetHashCode(); diff --git a/tests/Common/Common.cpp b/tests/Common/Common.cpp index 54110905b6..0c7c75855b 100644 --- a/tests/Common/Common.cpp +++ b/tests/Common/Common.cpp @@ -386,6 +386,14 @@ AbstractFoo::~AbstractFoo() { } +ImplementsAbstractFoo::ImplementsAbstractFoo() +{ +} + +ImplementsAbstractFoo::~ImplementsAbstractFoo() +{ +} + int ImplementsAbstractFoo::pureFunction(typedefInOverride i) { return 5; @@ -1349,6 +1357,11 @@ ReturnByValueWithReturnParam ReturnByValueWithReturnParamFactory::generate() return ReturnByValueWithReturnParam(); } +ImplementsAbstractFoo freeFunctionReturnsVirtualDtor() +{ + return ImplementsAbstractFoo(); +} + void integerOverload(int i) { } diff --git a/tests/Common/Common.h b/tests/Common/Common.h index 124d067a9c..5b233e5f65 100644 --- a/tests/Common/Common.h +++ b/tests/Common/Common.h @@ -268,6 +268,8 @@ class DLL_API AbstractFoo class DLL_API ImplementsAbstractFoo : public AbstractFoo { public: + ImplementsAbstractFoo(); + ~ImplementsAbstractFoo(); typedef int typedefInOverride; virtual int pureFunction(typedefInOverride i = 0); virtual int pureFunction1(); @@ -1455,6 +1457,7 @@ template using TypeAlias = InvokeGenSeq>; template struct DerivedTypeAlias : TypeAlias {}; +DLL_API ImplementsAbstractFoo freeFunctionReturnsVirtualDtor(); DLL_API void integerOverload(int i); DLL_API void integerOverload(unsigned int i); DLL_API void integerOverload(long i);