diff --git a/CfrontCodeGenerator.cpp b/CfrontCodeGenerator.cpp index 97c7d5f3..b7e32020 100644 --- a/CfrontCodeGenerator.cpp +++ b/CfrontCodeGenerator.cpp @@ -664,6 +664,8 @@ void CfrontCodeGenerator::InsertCXXMethodDecl(const CXXMethodDecl* stmt, SkipBod } else if(const auto* dtor = dyn_cast_or_null(stmt)) { // Based on: https://www.dre.vanderbilt.edu/~schmidt/PDF/C++-translation.pdf + InsertVtblPtr(stmt, stmt->getParent(), bodyStmts); + if(body) { bodyStmts.AddBodyStmts(body); } @@ -682,9 +684,9 @@ void CfrontCodeGenerator::InsertCXXMethodDecl(const CXXMethodDecl* stmt, SkipBod bodyStmts.Add( Call(GetSpecialMemberName(stmt, GetRecordDeclType(base.getType()->getAsRecordDecl())), {cast})); - - body = mkCompoundStmt({bodyStmts}); } + + body = mkCompoundStmt({bodyStmts}); } params_store params{}; diff --git a/tests/EduCfrontTest22.cpp b/tests/EduCfrontTest22.cpp index 3f26af65..3951f916 100644 --- a/tests/EduCfrontTest22.cpp +++ b/tests/EduCfrontTest22.cpp @@ -9,6 +9,8 @@ class Fruit { Print(); } + virtual ~Fruit() { Print(); } + virtual void Print() const { puts("Base"); } }; @@ -18,6 +20,8 @@ class Apple : public Fruit { : Fruit{} {} + virtual ~Apple() override { Print(); } + void Print() const override { puts("Apple"); } }; diff --git a/tests/EduCfrontTest22.expect b/tests/EduCfrontTest22.expect index 1b77bf7c..38ba99f1 100644 --- a/tests/EduCfrontTest22.expect +++ b/tests/EduCfrontTest22.expect @@ -26,10 +26,16 @@ typedef struct Fruit inline Fruit * Constructor_Fruit(Fruit * __this) { __this->__vptrFruit = __vtbl_array[0]; - (*((void (*)(const Fruit *))((__this)->__vptrFruit[0]).f))((((const Fruit *)(char *)(__this)) + ((__this)->__vptrFruit[0]).d)); + (*((void (*)(const Fruit *))((__this)->__vptrFruit[1]).f))((((const Fruit *)(char *)(__this)) + ((__this)->__vptrFruit[1]).d)); return __this; } +inline void Destructor_Fruit(Fruit * __this) +{ + __this->__vptrFruit = __vtbl_array[0]; + (*((void (*)(const Fruit *))((__this)->__vptrFruit[1]).f))((((const Fruit *)(char *)(__this)) + ((__this)->__vptrFruit[1]).d)); +} + inline void PrintFruit(const Fruit * __this) { puts("Base"); @@ -48,6 +54,12 @@ inline Apple * Constructor_Apple(Apple * __this) return __this; } +inline void Destructor_Apple(Apple * __this) +{ + (*((void (*)(const Apple *))((__this)->__vptrFruit[1]).f))((((const Apple *)(char *)(__this)) + ((__this)->__vptrFruit[1]).d)); + Destructor_Fruit((Fruit *)__this); +} + inline void PrintApple(const Apple * __this) { puts("Apple"); @@ -59,7 +71,7 @@ int __main(void) Apple x; Constructor_Apple((Apple *)&x); return 0; - /* x // lifetime ends here */ + (*((void (*)(Apple *))((&x)->__vptrFruit[0]).f))((((Apple *)(char *)(&x)) + ((&x)->__vptrFruit[0]).d)); } int main(void) @@ -71,8 +83,8 @@ int main(void) /* ret // lifetime ends here */ } -__mptr __vtbl_Fruit[1] = {0, 0, (__vptp)PrintFruit}; -__mptr __vtbl_Apple[1] = {0, 0, (__vptp)PrintApple}; +__mptr __vtbl_Fruit[2] = {{0, 0, (__vptp)Destructor_Fruit}, {0, 0, (__vptp)PrintFruit}}; +__mptr __vtbl_Apple[2] = {{0, 0, (__vptp)Destructor_Apple}, {0, 0, (__vptp)PrintApple}}; __mptr * __vtbl_array[2] = {__vtbl_Fruit, __vtbl_Apple}; diff --git a/tests/EduCfrontTest5.expect b/tests/EduCfrontTest5.expect index 4c2b1255..18637da9 100644 --- a/tests/EduCfrontTest5.expect +++ b/tests/EduCfrontTest5.expect @@ -50,6 +50,7 @@ typedef struct Base inline void Destructor_Base(Base * __this) { + __this->__vptrBase = __vtbl_array[0]; } inline Base * Constructor_Base(Base * __this) @@ -68,6 +69,7 @@ typedef struct BaseSecond inline void Destructor_BaseSecond(BaseSecond * __this) { + __this->__vptrBaseSecond = __vtbl_array[1]; } inline BaseSecond * Constructor_BaseSecond(BaseSecond * __this) diff --git a/tests/EduCfrontTest7.expect b/tests/EduCfrontTest7.expect index 54199ca2..78e9233d 100644 --- a/tests/EduCfrontTest7.expect +++ b/tests/EduCfrontTest7.expect @@ -48,6 +48,7 @@ typedef struct Base inline void Destructor_Base(Base * __this) { + __this->__vptrBase = __vtbl_array[0]; } inline Base * Constructor_Base(Base * __this) @@ -87,6 +88,7 @@ typedef struct BaseThird inline void Destructor_BaseThird(BaseThird * __this) { + __this->__vptrBaseThird = __vtbl_array[2]; } inline BaseThird * Constructor_BaseThird(BaseThird * __this) diff --git a/tests/EduCfrontVtable4Test.expect b/tests/EduCfrontVtable4Test.expect index a006e03f..bc77d84d 100644 --- a/tests/EduCfrontVtable4Test.expect +++ b/tests/EduCfrontVtable4Test.expect @@ -26,6 +26,7 @@ typedef struct A inline void Destructor_A(A * __this) { + __this->__vptrA = __vtbl_array[0]; puts("dtor"); } diff --git a/tests/EduCfrontVtable5Test.expect b/tests/EduCfrontVtable5Test.expect index f27e6ec5..76e689cc 100644 --- a/tests/EduCfrontVtable5Test.expect +++ b/tests/EduCfrontVtable5Test.expect @@ -25,6 +25,7 @@ typedef struct Base inline void Destructor_Base(Base * __this) { + __this->__vptrBase = __vtbl_array[0]; puts("~Base"); } diff --git a/tests/EduCfrontVtable7Test.expect b/tests/EduCfrontVtable7Test.expect index dce53b86..47457157 100644 --- a/tests/EduCfrontVtable7Test.expect +++ b/tests/EduCfrontVtable7Test.expect @@ -26,6 +26,7 @@ typedef struct Fruit inline void Destructor_Fruit(Fruit * __this) { + __this->__vptrFruit = __vtbl_array[0]; puts("~Fruit"); } diff --git a/tests/Issue701.expect b/tests/Issue701.expect index a475082d..e9374b7a 100644 --- a/tests/Issue701.expect +++ b/tests/Issue701.expect @@ -26,6 +26,7 @@ typedef struct Fruit inline void Destructor_Fruit(Fruit * __this) { + __this->__vptrFruit = __vtbl_array[0]; puts("~Fruit"); }