Skip to content

Commit c53f8b3

Browse files
committed
Fixed virtual destructor in Cfront mode.
1 parent 99986cc commit c53f8b3

9 files changed

+32
-6
lines changed

CfrontCodeGenerator.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,8 @@ 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+
InsertVtblPtr(stmt, stmt->getParent(), bodyStmts);
668+
667669
if(body) {
668670
bodyStmts.AddBodyStmts(body);
669671
}
@@ -682,9 +684,9 @@ void CfrontCodeGenerator::InsertCXXMethodDecl(const CXXMethodDecl* stmt, SkipBod
682684

683685
bodyStmts.Add(
684686
Call(GetSpecialMemberName(stmt, GetRecordDeclType(base.getType()->getAsRecordDecl())), {cast}));
685-
686-
body = mkCompoundStmt({bodyStmts});
687687
}
688+
689+
body = mkCompoundStmt({bodyStmts});
688690
}
689691

690692
params_store params{};

tests/EduCfrontTest22.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ class Fruit {
99
Print();
1010
}
1111

12+
virtual ~Fruit() { Print(); }
13+
1214
virtual void Print() const { puts("Base"); }
1315
};
1416

@@ -18,6 +20,8 @@ class Apple : public Fruit {
1820
: Fruit{}
1921
{}
2022

23+
virtual ~Apple() override { Print(); }
24+
2125
void Print() const override { puts("Apple"); }
2226
};
2327

tests/EduCfrontTest22.expect

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,16 @@ typedef struct Fruit
2626
inline Fruit * Constructor_Fruit(Fruit * __this)
2727
{
2828
__this->__vptrFruit = __vtbl_array[0];
29-
(*((void (*)(const Fruit *))((__this)->__vptrFruit[0]).f))((((const Fruit *)(char *)(__this)) + ((__this)->__vptrFruit[0]).d));
29+
(*((void (*)(const Fruit *))((__this)->__vptrFruit[1]).f))((((const Fruit *)(char *)(__this)) + ((__this)->__vptrFruit[1]).d));
3030
return __this;
3131
}
3232

33+
inline void Destructor_Fruit(Fruit * __this)
34+
{
35+
__this->__vptrFruit = __vtbl_array[0];
36+
(*((void (*)(const Fruit *))((__this)->__vptrFruit[1]).f))((((const Fruit *)(char *)(__this)) + ((__this)->__vptrFruit[1]).d));
37+
}
38+
3339
inline void PrintFruit(const Fruit * __this)
3440
{
3541
puts("Base");
@@ -48,6 +54,12 @@ inline Apple * Constructor_Apple(Apple * __this)
4854
return __this;
4955
}
5056

57+
inline void Destructor_Apple(Apple * __this)
58+
{
59+
(*((void (*)(const Apple *))((__this)->__vptrFruit[1]).f))((((const Apple *)(char *)(__this)) + ((__this)->__vptrFruit[1]).d));
60+
Destructor_Fruit((Fruit *)__this);
61+
}
62+
5163
inline void PrintApple(const Apple * __this)
5264
{
5365
puts("Apple");
@@ -59,7 +71,7 @@ int __main(void)
5971
Apple x;
6072
Constructor_Apple((Apple *)&x);
6173
return 0;
62-
/* x // lifetime ends here */
74+
(*((void (*)(Apple *))((&x)->__vptrFruit[0]).f))((((Apple *)(char *)(&x)) + ((&x)->__vptrFruit[0]).d));
6375
}
6476

6577
int main(void)
@@ -71,8 +83,8 @@ int main(void)
7183
/* ret // lifetime ends here */
7284
}
7385

74-
__mptr __vtbl_Fruit[1] = {0, 0, (__vptp)PrintFruit};
75-
__mptr __vtbl_Apple[1] = {0, 0, (__vptp)PrintApple};
86+
__mptr __vtbl_Fruit[2] = {{0, 0, (__vptp)Destructor_Fruit}, {0, 0, (__vptp)PrintFruit}};
87+
__mptr __vtbl_Apple[2] = {{0, 0, (__vptp)Destructor_Apple}, {0, 0, (__vptp)PrintApple}};
7688

7789
__mptr * __vtbl_array[2] = {__vtbl_Fruit, __vtbl_Apple};
7890

tests/EduCfrontTest5.expect

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ typedef struct Base
5050

5151
inline void Destructor_Base(Base * __this)
5252
{
53+
__this->__vptrBase = __vtbl_array[0];
5354
}
5455

5556
inline Base * Constructor_Base(Base * __this)
@@ -68,6 +69,7 @@ typedef struct BaseSecond
6869

6970
inline void Destructor_BaseSecond(BaseSecond * __this)
7071
{
72+
__this->__vptrBaseSecond = __vtbl_array[1];
7173
}
7274

7375
inline BaseSecond * Constructor_BaseSecond(BaseSecond * __this)

tests/EduCfrontTest7.expect

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ typedef struct Base
4848

4949
inline void Destructor_Base(Base * __this)
5050
{
51+
__this->__vptrBase = __vtbl_array[0];
5152
}
5253

5354
inline Base * Constructor_Base(Base * __this)
@@ -87,6 +88,7 @@ typedef struct BaseThird
8788

8889
inline void Destructor_BaseThird(BaseThird * __this)
8990
{
91+
__this->__vptrBaseThird = __vtbl_array[2];
9092
}
9193

9294
inline BaseThird * Constructor_BaseThird(BaseThird * __this)

tests/EduCfrontVtable4Test.expect

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ typedef struct A
2626

2727
inline void Destructor_A(A * __this)
2828
{
29+
__this->__vptrA = __vtbl_array[0];
2930
puts("dtor");
3031
}
3132

tests/EduCfrontVtable5Test.expect

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ typedef struct Base
2525

2626
inline void Destructor_Base(Base * __this)
2727
{
28+
__this->__vptrBase = __vtbl_array[0];
2829
puts("~Base");
2930
}
3031

tests/EduCfrontVtable7Test.expect

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ typedef struct Fruit
2626

2727
inline void Destructor_Fruit(Fruit * __this)
2828
{
29+
__this->__vptrFruit = __vtbl_array[0];
2930
puts("~Fruit");
3031
}
3132

tests/Issue701.expect

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ typedef struct Fruit
2626

2727
inline void Destructor_Fruit(Fruit * __this)
2828
{
29+
__this->__vptrFruit = __vtbl_array[0];
2930
puts("~Fruit");
3031
}
3132

0 commit comments

Comments
 (0)