Skip to content

Commit 0f407cd

Browse files
author
Daniel Kroening
committed
Merge pull request #77 from tautschnig/attribute-constructor
Support __attribute__((constructor))
2 parents 123fd85 + 3f01cce commit 0f407cd

8 files changed

+62
-5
lines changed

src/ansi-c/ansi_c_convert_type.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,10 @@ void ansi_c_convert_typet::read_rec(const typet &type)
229229
}
230230
else if(type.id()==ID_noreturn)
231231
c_qualifiers.is_noreturn=true;
232+
else if(type.id()==ID_constructor)
233+
constructor=true;
234+
else if(type.id()==ID_destructor)
235+
destructor=true;
232236
else
233237
other.push_back(type);
234238
}
@@ -274,6 +278,33 @@ void ansi_c_convert_typet::write(typet &type)
274278
}
275279

276280
type.swap(other.front());
281+
282+
if(constructor || destructor)
283+
{
284+
if(constructor && destructor)
285+
{
286+
err_location(source_location);
287+
str << "combining constructor and destructor not supported";
288+
error_msg();
289+
throw 0;
290+
}
291+
else if(type.id()!=ID_empty)
292+
{
293+
err_location(source_location);
294+
str << "constructor and destructor required to be type void";
295+
error_msg();
296+
throw 0;
297+
}
298+
299+
type.id(constructor ? ID_constructor : ID_destructor);
300+
}
301+
}
302+
else if(constructor || destructor)
303+
{
304+
err_location(source_location);
305+
str << "constructor and destructor required to be type void";
306+
error_msg();
307+
throw 0;
277308
}
278309
else if(gcc_float128_cnt)
279310
{

src/ansi-c/ansi_c_convert_type.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ class ansi_c_convert_typet:public message_streamt
3434
bool packed, aligned;
3535
exprt vector_size, alignment, bv_width, fraction_width;
3636
exprt msc_based; // this is Visual Studio
37+
bool constructor, destructor;
3738

3839
// storage spec
3940
c_storage_spect c_storage_spec;
@@ -67,7 +68,7 @@ class ansi_c_convert_typet:public message_streamt
6768
msc_based.make_nil();
6869
gcc_attribute_mode.make_nil();
6970

70-
packed=aligned=false;
71+
packed=aligned=constructor=destructor=false;
7172

7273
other.clear();
7374
c_storage_spec.clear();

src/ansi-c/expr2c.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -694,6 +694,11 @@ std::string expr2ct::convert_rec(
694694
{
695695
return q+"__builtin_va_list"+d;
696696
}
697+
else if(src.id()==ID_constructor ||
698+
src.id()==ID_destructor)
699+
{
700+
return q+"__attribute__(("+id2string(src.id())+")) void"+d;
701+
}
697702

698703
{
699704
lispexprt lisp;

src/ansi-c/parser.y

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,8 @@ extern char *yyansi_ctext;
133133
%token TOK_GCC_ATTRIBUTE_GNU_INLINE "__gnu_inline__"
134134
%token TOK_GCC_ATTRIBUTE_WEAK "weak"
135135
%token TOK_GCC_ATTRIBUTE_NORETURN "noreturn"
136+
%token TOK_GCC_ATTRIBUTE_CONSTRUCTOR "constructor"
137+
%token TOK_GCC_ATTRIBUTE_DESTRUCTOR "destructor"
136138
%token TOK_GCC_ATTRIBUTE_END ")"
137139
%token TOK_GCC_LABEL "__label__"
138140
%token TOK_MSC_ASM "__asm"
@@ -1566,6 +1568,10 @@ gcc_type_attribute:
15661568
{ $$=$1; set($$, ID_noreturn); }
15671569
| TOK_GCC_ATTRIBUTE_NORETURN TOK_GCC_ATTRIBUTE_END
15681570
{ $$=$1; set($$, ID_noreturn); }
1571+
| TOK_GCC_ATTRIBUTE_CONSTRUCTOR TOK_GCC_ATTRIBUTE_END
1572+
{ $$=$1; set($$, ID_constructor); }
1573+
| TOK_GCC_ATTRIBUTE_DESTRUCTOR TOK_GCC_ATTRIBUTE_END
1574+
{ $$=$1; set($$, ID_destructor); }
15691575
| gcc_attribute_specifier
15701576
;
15711577

src/ansi-c/scanner.l

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,6 +1378,12 @@ __decltype { if(PARSER.cpp98 && PARSER.mode==ansi_c_parsert::GCC)
13781378
"noreturn" |
13791379
"__noreturn__" { BEGIN(GCC_ATTRIBUTE3); loc(); return TOK_GCC_ATTRIBUTE_NORETURN; }
13801380

1381+
"constructor" |
1382+
"__constructor__" { BEGIN(GCC_ATTRIBUTE3); loc(); return TOK_GCC_ATTRIBUTE_CONSTRUCTOR; }
1383+
1384+
"destructor" |
1385+
"__destructor__" { BEGIN(GCC_ATTRIBUTE3); loc(); return TOK_GCC_ATTRIBUTE_DESTRUCTOR; }
1386+
13811387
{ws} { /* ignore */ }
13821388
{newline} { /* ignore */ }
13831389
{identifier} { BEGIN(GCC_ATTRIBUTE4); }

src/cpp/cpp_typecheck.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -301,8 +301,7 @@ void cpp_typecheckt::static_and_dynamic_initialization()
301301
init_symbol.mode=ID_cpp;
302302
init_symbol.module=module;
303303
init_symbol.type=code_typet();
304-
init_symbol.type.add(ID_return_type)=typet(ID_empty);
305-
init_symbol.type.set("initialization", true);
304+
init_symbol.type.add(ID_return_type)=typet(ID_constructor);
306305
init_symbol.is_type=false;
307306
init_symbol.is_macro=false;
308307

src/linking/remove_internal_symbols.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,15 @@ void remove_internal_symbols(
132132
symbol.value.is_not_nil() &&
133133
!symbol.value.get_bool(ID_C_zero_initializer);
134134

135+
// __attribute__((constructor)), __attribute__((destructor))
136+
if(symbol.mode==ID_C && is_function && is_file_local)
137+
{
138+
const code_typet &code_type=to_code_type(symbol.type);
139+
if(code_type.return_type().id()==ID_constructor ||
140+
code_type.return_type().id()==ID_destructor)
141+
is_file_local=false;
142+
}
143+
135144
if(is_type)
136145
{
137146
// never EXPORTED by itself

src/linking/static_lifetime_init.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -160,8 +160,8 @@ bool static_lifetime_init(
160160
{
161161
const symbolt &symbol=ns.lookup(id);
162162

163-
if(symbol.type.get_bool("initialization") &&
164-
symbol.type.id()==ID_code)
163+
if(symbol.type.id()==ID_code &&
164+
to_code_type(symbol.type).return_type().id()==ID_constructor)
165165
{
166166
code_function_callt function_call;
167167
function_call.function()=symbol.symbol_expr();

0 commit comments

Comments
 (0)