Skip to content

Commit b1cd9e2

Browse files
committed
Constructor/destructor attributes also work with forward declarations
GCC and Clang accept and apply these attributes when they are part of the forward declaration, the definition, or both.
1 parent 4af9c8a commit b1cd9e2

File tree

2 files changed

+23
-7
lines changed

2 files changed

+23
-7
lines changed

regression/cbmc/constructor1/main.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
#include <assert.h>
22

33
#ifdef __GNUC__
4-
int x, y;
4+
int x, y, z;
55

66
// forward declaration with and without attribute is ok
77
static __attribute__((constructor)) void format_init(void);
88
static void other_init(void);
9+
static __attribute__((constructor)) void more_init(void);
910

1011
static __attribute__((constructor))
1112
void format_init(void)
@@ -18,13 +19,19 @@ static __attribute__((constructor)) void other_init(void)
1819
{
1920
y = 42;
2021
}
22+
23+
static void more_init(void)
24+
{
25+
z = 42;
26+
}
2127
#endif
2228

2329
int main()
2430
{
2531
#ifdef __GNUC__
2632
assert(x==42);
2733
assert(y == 42);
34+
assert(z == 42);
2835
#endif
2936
return 0;
3037
}

src/ansi-c/c_typecheck_base.cpp

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -379,12 +379,21 @@ void c_typecheck_baset::typecheck_redefinition_non_type(
379379
new_ct.return_type().id() != ID_constructor &&
380380
new_ct.return_type().id() != ID_destructor)
381381
{
382-
throw invalid_source_file_exceptiont{
383-
"function symbol '" + id2string(new_symbol.display_name()) +
384-
"' redefined with a different type:\n" +
385-
"Original: " + to_string(old_symbol.type) + "\n" +
386-
" New: " + to_string(new_symbol.type),
387-
new_symbol.location};
382+
if(
383+
old_ct.return_type().id() == ID_constructor ||
384+
old_ct.return_type().id() == ID_destructor)
385+
{
386+
new_ct = old_ct;
387+
}
388+
else
389+
{
390+
throw invalid_source_file_exceptiont{
391+
"function symbol '" + id2string(new_symbol.display_name()) +
392+
"' redefined with a different type:\n" +
393+
"Original: " + to_string(old_symbol.type) + "\n" +
394+
" New: " + to_string(new_symbol.type),
395+
new_symbol.location};
396+
}
388397
}
389398
const bool inlined = old_ct.get_inlined() || new_ct.get_inlined();
390399

0 commit comments

Comments
 (0)