Skip to content

Commit e5e3835

Browse files
committed
Fixed #507: Improved support for static variables.
1 parent 64ab34b commit e5e3835

14 files changed

Lines changed: 91 additions & 16 deletions

ASTHelpers.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -680,6 +680,12 @@ BinaryOperator* Mul(Expr* lhs, Expr* rhs)
680680
}
681681
//-----------------------------------------------------------------------------
682682

683+
BinaryOperator* And(VarDecl* lhs, Expr* rhs)
684+
{
685+
return mkBinaryOperator(mkDeclRefExpr(lhs), rhs, BinaryOperator::Opcode::BO_And, lhs->getType());
686+
}
687+
//-----------------------------------------------------------------------------
688+
683689
void StmtsContainer::AddBodyStmts(Stmt* body)
684690
{
685691
if(auto* b = dyn_cast_or_null<CompoundStmt>(body)) {

ASTHelpers.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ CXXBoolLiteralExpr* Bool(bool b);
5454
CallExpr* CallDestructor(const VarDecl* fieldDecl);
5555
CXXNewExpr* New(ArrayRef<Expr*> placementArgs, const Expr* expr, QualType t);
5656
BinaryOperator* Mul(Expr* lhs, Expr* rhs);
57+
BinaryOperator* And(VarDecl* lhs, Expr* rhs);
5758
QualType Typedef(std::string_view name, QualType underlayingType);
5859

5960
SmallVector<Expr*, 5> ArgsToExprVector(const Expr* expr);

CodeGenerator.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4594,14 +4594,16 @@ void CodeGenerator::HandleLocalStaticNonTrivialClass(const VarDecl* stmt)
45944594

45954595
if(threadSafe) {
45964596
innerBodyStmts.AddBodyStmts(Call("__cxa_guard_release"sv, {Ref(compilerGuardVar)}));
4597+
innerBodyStmts.Add(Comment(
4598+
StrCat("__cxa_atexit("sv, typeName, "::~"sv, typeName, ", &"sv, internalVarName, ", &__dso_handle);"sv)));
45974599

45984600
auto* aquireIf = If(Call("__cxa_guard_acquire"sv, {Ref(compilerGuardVar)}), innerBodyStmts);
45994601
bodyStmts.AddBodyStmts(aquireIf);
46004602
} else {
46014603
bodyStmts.AddBodyStmts(allocAndFlagBodyCompound);
46024604
}
46034605

4604-
InsertArg(If(Not(compilerGuardVar), bodyStmts));
4606+
InsertArg(If(Equal(And(compilerGuardVar, Int32(0xff)), Int32(0)), bodyStmts));
46054607
}
46064608
//-----------------------------------------------------------------------------
46074609

tests/Issue369.expect

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const foo & create()
1313
static uint64_t __valueGuard;
1414
alignas(const foo) static char __value[sizeof(const foo)];
1515

16-
if(!__valueGuard) {
16+
if((__valueGuard & 255) == 0) {
1717
if(__cxa_guard_acquire(&__valueGuard)) {
1818
try
1919
{
@@ -24,6 +24,7 @@ const foo & create()
2424
throw ;
2525
}
2626
__cxa_guard_release(&__valueGuard);
27+
/* __cxa_atexit(const foo::~const foo, &__value, &__dso_handle); */
2728
}
2829

2930
}

tests/Issue369_1.expect

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ const foo & create()
3838
static uint64_t __valueGuard;
3939
alignas(foo) static char __value[sizeof(foo)];
4040

41-
if(!__valueGuard) {
41+
if((__valueGuard & 255) == 0) {
4242
if(__cxa_guard_acquire(&__valueGuard)) {
4343
try
4444
{
@@ -49,6 +49,7 @@ const foo & create()
4949
throw ;
5050
}
5151
__cxa_guard_release(&__valueGuard);
52+
/* __cxa_atexit(foo::~foo, &__value, &__dso_handle); */
5253
}
5354

5455
}

tests/Issue369_2.expect

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,11 +38,12 @@ const void withNoexcept()
3838
static uint64_t __valueGuard;
3939
alignas(foo) static char __value[sizeof(foo)];
4040

41-
if(!__valueGuard) {
41+
if((__valueGuard & 255) == 0) {
4242
if(__cxa_guard_acquire(&__valueGuard)) {
4343
new (&__value)foo{std::move(__lambda_4_23.operator()())};
4444
__valueGuard = true;
4545
__cxa_guard_release(&__valueGuard);
46+
/* __cxa_atexit(foo::~foo, &__value, &__dso_handle); */
4647
}
4748

4849
}
@@ -78,7 +79,7 @@ const void withNoexceptFalse()
7879
static uint64_t __valueGuard;
7980
alignas(foo) static char __value[sizeof(foo)];
8081

81-
if(!__valueGuard) {
82+
if((__valueGuard & 255) == 0) {
8283
if(__cxa_guard_acquire(&__valueGuard)) {
8384
try
8485
{
@@ -89,6 +90,7 @@ const void withNoexceptFalse()
8990
throw ;
9091
}
9192
__cxa_guard_release(&__valueGuard);
93+
/* __cxa_atexit(foo::~foo, &__value, &__dso_handle); */
9294
}
9395

9496
}
@@ -124,11 +126,12 @@ const void withNoexceptTrue()
124126
static uint64_t __valueGuard;
125127
alignas(foo) static char __value[sizeof(foo)];
126128

127-
if(!__valueGuard) {
129+
if((__valueGuard & 255) == 0) {
128130
if(__cxa_guard_acquire(&__valueGuard)) {
129131
new (&__value)foo{std::move(__lambda_12_23.operator()())};
130132
__valueGuard = true;
131133
__cxa_guard_release(&__valueGuard);
134+
/* __cxa_atexit(foo::~foo, &__value, &__dso_handle); */
132135
}
133136

134137
}
@@ -179,7 +182,7 @@ void viaFunction()
179182
static uint64_t __fGuard;
180183
alignas(foo) static char __f[sizeof(foo)];
181184

182-
if(!__fGuard) {
185+
if((__fGuard & 255) == 0) {
183186
if(__cxa_guard_acquire(&__fGuard)) {
184187
try
185188
{
@@ -190,6 +193,7 @@ void viaFunction()
190193
throw ;
191194
}
192195
__cxa_guard_release(&__fGuard);
196+
/* __cxa_atexit(foo::~foo, &__f, &__dso_handle); */
193197
}
194198

195199
}

tests/Issue507.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
struct example_struct
2+
{
3+
example_struct() { throw; }
4+
~example_struct() { }
5+
};
6+
7+
example_struct& get_example()
8+
{
9+
static example_struct temp;
10+
return temp;
11+
}
12+

tests/Issue507.expect

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include <new> // for thread-safe static's placement new
2+
#include <stdint.h> // for uint64_t under Linux/GCC
3+
4+
struct example_struct
5+
{
6+
inline example_struct()
7+
{
8+
throw ;
9+
}
10+
11+
inline ~example_struct() noexcept
12+
{
13+
}
14+
15+
};
16+
17+
18+
example_struct & get_example()
19+
{
20+
static uint64_t __tempGuard;
21+
alignas(example_struct) static char __temp[sizeof(example_struct)];
22+
23+
if((__tempGuard & 255) == 0) {
24+
if(__cxa_guard_acquire(&__tempGuard)) {
25+
try
26+
{
27+
new (&__temp)example_struct();
28+
__tempGuard = true;
29+
} catch(...) {
30+
__cxa_guard_abort(&__tempGuard);
31+
throw ;
32+
}
33+
__cxa_guard_release(&__tempGuard);
34+
/* __cxa_atexit(example_struct::~example_struct, &__temp, &__dso_handle); */
35+
}
36+
37+
}
38+
39+
return *reinterpret_cast<example_struct*>(__temp);
40+
}

tests/StaticHandler4Test.expect

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Sing & Test()
2323
static uint64_t __sGuard;
2424
alignas(Sing) static char __s[sizeof(Sing)];
2525

26-
if(!__sGuard) {
26+
if((__sGuard & 255) == 0) {
2727
if(__cxa_guard_acquire(&__sGuard)) {
2828
try
2929
{
@@ -34,6 +34,7 @@ Sing & Test()
3434
throw ;
3535
}
3636
__cxa_guard_release(&__sGuard);
37+
/* __cxa_atexit(Sing::~Sing, &__s, &__dso_handle); */
3738
}
3839

3940
}

tests/StaticHandler5Test.expect

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ Sing & Test()
2323
static bool __sGuard;
2424
alignas(Sing) static char __s[sizeof(Sing)];
2525

26-
if(!__sGuard) {
26+
if((__sGuard & 255) == 0) {
2727
new (&__s)Sing();
2828
__sGuard = true;
2929
}

0 commit comments

Comments
 (0)