Skip to content

Commit 99986cc

Browse files
Merge pull request #732 from andreasfertig/fixCfrontCtor
Fixed missing vtable assignment in user provided constructor.
2 parents fca6fb6 + 0f59099 commit 99986cc

File tree

3 files changed

+121
-0
lines changed

3 files changed

+121
-0
lines changed

CfrontCodeGenerator.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,13 @@ void CfrontCodeGenerator::InsertCXXMethodDecl(const CXXMethodDecl* stmt, SkipBod
626626
bodyStmts.AddBodyStmts(
627627
Call(GetSpecialMemberName(stmt, GetRecordDeclType(ctorType->getAsRecordDecl())), callParams));
628628
}
629+
630+
// insert our vtable pointer
631+
InsertVtblPtr(stmt, stmt->getParent(), bodyStmts);
632+
// in case of multi inheritance insert additional vtable pointers
633+
for(const auto& base : parent->bases()) {
634+
InsertVtblPtr(stmt, base.getType()->getAsCXXRecordDecl(), bodyStmts);
635+
}
629636
}
630637

631638
if(body) {

tests/EduCfrontTest22.cpp

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// cmdlineinsights:-edu-show-cfront
2+
3+
#include <cstdio>
4+
5+
class Fruit {
6+
public:
7+
Fruit()
8+
{
9+
Print();
10+
}
11+
12+
virtual void Print() const { puts("Base"); }
13+
};
14+
15+
class Apple : public Fruit {
16+
public:
17+
Apple()
18+
: Fruit{}
19+
{}
20+
21+
void Print() const override { puts("Apple"); }
22+
};
23+
24+
int main()
25+
{
26+
Apple x{};
27+
}
28+

tests/EduCfrontTest22.expect

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*************************************************************************************
2+
* NOTE: This an educational hand-rolled transformation. Things can be incorrect or *
3+
* buggy. *
4+
*************************************************************************************/
5+
void __cxa_start(void);
6+
void __cxa_atexit(void);
7+
typedef int (*__vptp)();
8+
9+
struct __mptr
10+
{
11+
short d;
12+
short i;
13+
__vptp f;
14+
};
15+
16+
extern struct __mptr* __vtbl_array[];
17+
18+
19+
#include <cstdio>
20+
21+
typedef struct Fruit
22+
{
23+
__mptr * __vptrFruit;
24+
} Fruit;
25+
26+
inline Fruit * Constructor_Fruit(Fruit * __this)
27+
{
28+
__this->__vptrFruit = __vtbl_array[0];
29+
(*((void (*)(const Fruit *))((__this)->__vptrFruit[0]).f))((((const Fruit *)(char *)(__this)) + ((__this)->__vptrFruit[0]).d));
30+
return __this;
31+
}
32+
33+
inline void PrintFruit(const Fruit * __this)
34+
{
35+
puts("Base");
36+
}
37+
38+
39+
typedef struct Apple
40+
{
41+
__mptr * __vptrFruit;
42+
} Apple;
43+
44+
inline Apple * Constructor_Apple(Apple * __this)
45+
{
46+
Constructor_Fruit((Fruit *)__this);
47+
__this->__vptrFruit = __vtbl_array[1];
48+
return __this;
49+
}
50+
51+
inline void PrintApple(const Apple * __this)
52+
{
53+
puts("Apple");
54+
}
55+
56+
57+
int __main(void)
58+
{
59+
Apple x;
60+
Constructor_Apple((Apple *)&x);
61+
return 0;
62+
/* x // lifetime ends here */
63+
}
64+
65+
int main(void)
66+
{
67+
__cxa_start();
68+
int ret = __main();
69+
__cxa_atexit();
70+
return ret;
71+
/* ret // lifetime ends here */
72+
}
73+
74+
__mptr __vtbl_Fruit[1] = {0, 0, (__vptp)PrintFruit};
75+
__mptr __vtbl_Apple[1] = {0, 0, (__vptp)PrintApple};
76+
77+
__mptr * __vtbl_array[2] = {__vtbl_Fruit, __vtbl_Apple};
78+
79+
void __cxa_start(void)
80+
{
81+
}
82+
83+
void __cxa_atexit(void)
84+
{
85+
}
86+

0 commit comments

Comments
 (0)