Skip to content

Commit 0f2e7fe

Browse files
committed
Fixed cfront mode destructor or derived classes.
1 parent 5afed88 commit 0f2e7fe

9 files changed

+68
-9
lines changed

CfrontCodeGenerator.cpp

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -664,14 +664,22 @@ void CfrontCodeGenerator::InsertCXXMethodDecl(const CXXMethodDecl* stmt, SkipBod
664664
} else if(const auto* dtor = dyn_cast_or_null<CXXDestructorDecl>(stmt)) {
665665
// Based on: https://www.dre.vanderbilt.edu/~schmidt/PDF/C++-translation.pdf
666666

667+
if(not HasDtor(GetRecordDeclType(dtor->getParent()))) {
668+
return;
669+
}
670+
667671
InsertVtblPtr(stmt, stmt->getParent(), bodyStmts);
668672

669-
if(body) {
670-
bodyStmts.AddBodyStmts(body);
673+
for(const auto& base : llvm::reverse(dtor->getParent()->bases())) {
674+
if(not dtor->isVirtual()) {
675+
continue;
676+
}
677+
678+
InsertVtblPtr(stmt, dyn_cast_or_null<CXXRecordDecl>(base.getType()->getAsRecordDecl()), bodyStmts);
671679
}
672680

673-
if(not HasDtor(GetRecordDeclType(dtor->getParent()))) {
674-
return;
681+
if(body) {
682+
bodyStmts.AddBodyStmts(body);
675683
}
676684

677685
for(const auto& base : llvm::reverse(dtor->getParent()->bases())) {

tests/EduCfrontTest22.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,20 @@ class Apple : public Fruit {
2525
void Print() const override { puts("Apple"); }
2626
};
2727

28+
class Orange : public Apple {
29+
public:
30+
Orange()
31+
: Apple{}
32+
{}
33+
34+
virtual ~Orange() override { Print(); }
35+
36+
void Print() const override { puts("Orange"); }
37+
};
38+
39+
2840
int main()
2941
{
30-
Apple x{};
42+
Orange x{};
3143
}
3244

tests/EduCfrontTest22.expect

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ inline Apple * Constructor_Apple(Apple * __this)
5656

5757
inline void Destructor_Apple(Apple * __this)
5858
{
59+
__this->__vptrFruit = __vtbl_array[1];
5960
(*((void (*)(const Apple *))((__this)->__vptrFruit[1]).f))((((const Apple *)(char *)(__this)) + ((__this)->__vptrFruit[1]).d));
6061
Destructor_Fruit((Fruit *)__this);
6162
}
@@ -66,12 +67,37 @@ inline void PrintApple(const Apple * __this)
6667
}
6768

6869

70+
typedef struct Orange
71+
{
72+
__mptr * __vptrFruit;
73+
} Orange;
74+
75+
inline Orange * Constructor_Orange(Orange * __this)
76+
{
77+
Constructor_Apple((Apple *)__this);
78+
__this->__vptrFruit = __vtbl_array[2];
79+
return __this;
80+
}
81+
82+
inline void Destructor_Orange(Orange * __this)
83+
{
84+
__this->__vptrFruit = __vtbl_array[2];
85+
(*((void (*)(const Orange *))((__this)->__vptrFruit[1]).f))((((const Orange *)(char *)(__this)) + ((__this)->__vptrFruit[1]).d));
86+
Destructor_Apple((Apple *)__this);
87+
}
88+
89+
inline void PrintOrange(const Orange * __this)
90+
{
91+
puts("Orange");
92+
}
93+
94+
6995
int __main(void)
7096
{
71-
Apple x;
72-
Constructor_Apple((Apple *)&x);
97+
Orange x;
98+
Constructor_Orange((Orange *)&x);
7399
return 0;
74-
(*((void (*)(Apple *))((&x)->__vptrFruit[0]).f))((((Apple *)(char *)(&x)) + ((&x)->__vptrFruit[0]).d));
100+
(*((void (*)(Orange *))((&x)->__vptrFruit[0]).f))((((Orange *)(char *)(&x)) + ((&x)->__vptrFruit[0]).d));
75101
}
76102

77103
int main(void)
@@ -85,8 +111,9 @@ int main(void)
85111

86112
__mptr __vtbl_Fruit[2] = {{0, 0, (__vptp)Destructor_Fruit}, {0, 0, (__vptp)PrintFruit}};
87113
__mptr __vtbl_Apple[2] = {{0, 0, (__vptp)Destructor_Apple}, {0, 0, (__vptp)PrintApple}};
114+
__mptr __vtbl_Orange[2] = {{0, 0, (__vptp)Destructor_Orange}, {0, 0, (__vptp)PrintOrange}};
88115

89-
__mptr * __vtbl_array[2] = {__vtbl_Fruit, __vtbl_Apple};
116+
__mptr * __vtbl_array[3] = {__vtbl_Fruit, __vtbl_Apple, __vtbl_Orange};
90117

91118
void __cxa_start(void)
92119
{

tests/EduCfrontTest5.expect

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ typedef struct Derived
9292

9393
inline void Destructor_Derived(Derived * __this)
9494
{
95+
__this->__vptrBaseSecond = __vtbl_array[3];
96+
__this->__vptrBase = __vtbl_array[2];
9597
__this->mD = 7;
9698
Destructor_BaseSecond((BaseSecond *)__this);
9799
Destructor_Base((Base *)__this);

tests/EduCfrontTest7.expect

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ typedef struct BaseSecond
6868

6969
inline void Destructor_BaseSecond(BaseSecond * __this)
7070
{
71+
__this->__vptrBase = __vtbl_array[1];
7172
Destructor_Base((Base *)__this);
7273
}
7374

@@ -113,6 +114,8 @@ typedef struct Derived
113114

114115
inline void Destructor_Derived(Derived * __this)
115116
{
117+
__this->__vptrBaseThird = __vtbl_array[4];
118+
__this->__vptrBase = __vtbl_array[3];
116119
__this->mD = 7;
117120
Destructor_BaseThird((BaseThird *)__this);
118121
Destructor_BaseSecond((BaseSecond *)__this);

tests/EduCfrontVtable4Test.expect

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ inline void OtherB(B * __this)
6060

6161
inline void Destructor_B(B * __this)
6262
{
63+
__this->__vptrA = __vtbl_array[1];
6364
Destructor_A((A *)__this);
6465
}
6566

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

9293
inline void Destructor_C(C * __this)
9394
{
95+
__this->__vptrA = __vtbl_array[2];
9496
Destructor_B((B *)__this);
9597
}
9698

tests/EduCfrontVtable5Test.expect

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ typedef struct Derived
4343

4444
inline void Destructor_Derived(Derived * __this)
4545
{
46+
__this->__vptrBase = __vtbl_array[1];
4647
puts("~Derived");
4748
Destructor_Base((Base *)__this);
4849
}

tests/EduCfrontVtable7Test.expect

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ inline void FunApple(Apple * __this)
5656

5757
inline void Destructor_Apple(Apple * __this)
5858
{
59+
__this->__vptrFruit = __vtbl_array[1];
5960
Destructor_Fruit((Fruit *)__this);
6061
}
6162

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

8485
inline void Destructor_PinkLady(PinkLady * __this)
8586
{
87+
__this->__vptrFruit = __vtbl_array[2];
8688
Destructor_Apple((Apple *)__this);
8789
}
8890

tests/Issue701.expect

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ inline void PrintApple(Apple * __this)
5757

5858
inline void Destructor_Apple(Apple * __this)
5959
{
60+
__this->__vptrFruit = __vtbl_array[1];
6061
Destructor_Fruit((Fruit *)__this);
6162
}
6263

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

8586
inline void Destructor_PinkLady(PinkLady * __this)
8687
{
88+
__this->__vptrFruit = __vtbl_array[2];
8789
Destructor_Apple((Apple *)__this);
8890
}
8991

0 commit comments

Comments
 (0)