Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions CfrontCodeGenerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -664,14 +664,22 @@ void CfrontCodeGenerator::InsertCXXMethodDecl(const CXXMethodDecl* stmt, SkipBod
} else if(const auto* dtor = dyn_cast_or_null<CXXDestructorDecl>(stmt)) {
// Based on: https://www.dre.vanderbilt.edu/~schmidt/PDF/C++-translation.pdf

if(not HasDtor(GetRecordDeclType(dtor->getParent()))) {
return;
}

InsertVtblPtr(stmt, stmt->getParent(), bodyStmts);

if(body) {
bodyStmts.AddBodyStmts(body);
for(const auto& base : llvm::reverse(dtor->getParent()->bases())) {
if(not dtor->isVirtual()) {
continue;
}

InsertVtblPtr(stmt, dyn_cast_or_null<CXXRecordDecl>(base.getType()->getAsRecordDecl()), bodyStmts);
}

if(not HasDtor(GetRecordDeclType(dtor->getParent()))) {
return;
if(body) {
bodyStmts.AddBodyStmts(body);
}

for(const auto& base : llvm::reverse(dtor->getParent()->bases())) {
Expand Down
14 changes: 13 additions & 1 deletion tests/EduCfrontTest22.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,20 @@ class Apple : public Fruit {
void Print() const override { puts("Apple"); }
};

class Orange : public Apple {
public:
Orange()
: Apple{}
{}

virtual ~Orange() override { Print(); }

void Print() const override { puts("Orange"); }
};


int main()
{
Apple x{};
Orange x{};
}

35 changes: 31 additions & 4 deletions tests/EduCfrontTest22.expect
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ inline Apple * Constructor_Apple(Apple * __this)

inline void Destructor_Apple(Apple * __this)
{
__this->__vptrFruit = __vtbl_array[1];
(*((void (*)(const Apple *))((__this)->__vptrFruit[1]).f))((((const Apple *)(char *)(__this)) + ((__this)->__vptrFruit[1]).d));
Destructor_Fruit((Fruit *)__this);
}
Expand All @@ -66,12 +67,37 @@ inline void PrintApple(const Apple * __this)
}


typedef struct Orange
{
__mptr * __vptrFruit;
} Orange;

inline Orange * Constructor_Orange(Orange * __this)
{
Constructor_Apple((Apple *)__this);
__this->__vptrFruit = __vtbl_array[2];
return __this;
}

inline void Destructor_Orange(Orange * __this)
{
__this->__vptrFruit = __vtbl_array[2];
(*((void (*)(const Orange *))((__this)->__vptrFruit[1]).f))((((const Orange *)(char *)(__this)) + ((__this)->__vptrFruit[1]).d));
Destructor_Apple((Apple *)__this);
}

inline void PrintOrange(const Orange * __this)
{
puts("Orange");
}


int __main(void)
{
Apple x;
Constructor_Apple((Apple *)&x);
Orange x;
Constructor_Orange((Orange *)&x);
return 0;
(*((void (*)(Apple *))((&x)->__vptrFruit[0]).f))((((Apple *)(char *)(&x)) + ((&x)->__vptrFruit[0]).d));
(*((void (*)(Orange *))((&x)->__vptrFruit[0]).f))((((Orange *)(char *)(&x)) + ((&x)->__vptrFruit[0]).d));
}

int main(void)
Expand All @@ -85,8 +111,9 @@ int main(void)

__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_Orange[2] = {{0, 0, (__vptp)Destructor_Orange}, {0, 0, (__vptp)PrintOrange}};

__mptr * __vtbl_array[2] = {__vtbl_Fruit, __vtbl_Apple};
__mptr * __vtbl_array[3] = {__vtbl_Fruit, __vtbl_Apple, __vtbl_Orange};

void __cxa_start(void)
{
Expand Down
2 changes: 2 additions & 0 deletions tests/EduCfrontTest5.expect
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,8 @@ typedef struct Derived

inline void Destructor_Derived(Derived * __this)
{
__this->__vptrBaseSecond = __vtbl_array[3];
__this->__vptrBase = __vtbl_array[2];
__this->mD = 7;
Destructor_BaseSecond((BaseSecond *)__this);
Destructor_Base((Base *)__this);
Expand Down
3 changes: 3 additions & 0 deletions tests/EduCfrontTest7.expect
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ typedef struct BaseSecond

inline void Destructor_BaseSecond(BaseSecond * __this)
{
__this->__vptrBase = __vtbl_array[1];
Destructor_Base((Base *)__this);
}

Expand Down Expand Up @@ -113,6 +114,8 @@ typedef struct Derived

inline void Destructor_Derived(Derived * __this)
{
__this->__vptrBaseThird = __vtbl_array[4];
__this->__vptrBase = __vtbl_array[3];
__this->mD = 7;
Destructor_BaseThird((BaseThird *)__this);
Destructor_BaseSecond((BaseSecond *)__this);
Expand Down
2 changes: 2 additions & 0 deletions tests/EduCfrontVtable4Test.expect
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ inline void OtherB(B * __this)

inline void Destructor_B(B * __this)
{
__this->__vptrA = __vtbl_array[1];
Destructor_A((A *)__this);
}

Expand Down Expand Up @@ -91,6 +92,7 @@ inline void OtherC(C * __this)

inline void Destructor_C(C * __this)
{
__this->__vptrA = __vtbl_array[2];
Destructor_B((B *)__this);
}

Expand Down
1 change: 1 addition & 0 deletions tests/EduCfrontVtable5Test.expect
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ typedef struct Derived

inline void Destructor_Derived(Derived * __this)
{
__this->__vptrBase = __vtbl_array[1];
puts("~Derived");
Destructor_Base((Base *)__this);
}
Expand Down
2 changes: 2 additions & 0 deletions tests/EduCfrontVtable7Test.expect
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ inline void FunApple(Apple * __this)

inline void Destructor_Apple(Apple * __this)
{
__this->__vptrFruit = __vtbl_array[1];
Destructor_Fruit((Fruit *)__this);
}

Expand Down Expand Up @@ -83,6 +84,7 @@ inline void FunPinkLady(PinkLady * __this)

inline void Destructor_PinkLady(PinkLady * __this)
{
__this->__vptrFruit = __vtbl_array[2];
Destructor_Apple((Apple *)__this);
}

Expand Down
2 changes: 2 additions & 0 deletions tests/Issue701.expect
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ inline void PrintApple(Apple * __this)

inline void Destructor_Apple(Apple * __this)
{
__this->__vptrFruit = __vtbl_array[1];
Destructor_Fruit((Fruit *)__this);
}

Expand Down Expand Up @@ -84,6 +85,7 @@ inline void PrintPinkLady(PinkLady * __this)

inline void Destructor_PinkLady(PinkLady * __this)
{
__this->__vptrFruit = __vtbl_array[2];
Destructor_Apple((Apple *)__this);
}

Expand Down
Loading