Skip to content

Commit d7bbf63

Browse files
Invoke functions marked __attribute__((destructor))
This is a GCC extension that our front-end parses, but an implementation of the desired semantics was hitherto missing. Co-authored-by: Chris Ryder <[email protected]>
1 parent cc9d04e commit d7bbf63

File tree

3 files changed

+48
-0
lines changed

3 files changed

+48
-0
lines changed

regression/cbmc/destructor1/main.c

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
#include <assert.h>
2+
3+
#ifdef __GNUC__
4+
// Will be implicitly invoked after main() completes if the attribute is
5+
// properly supported
6+
static __attribute__((destructor)) void assert_false(void)
7+
{
8+
assert(0);
9+
}
10+
#endif
11+
12+
int main()
13+
{
14+
#ifndef __GNUC__
15+
// explicitly invoke assert_false as __attribute__((destructor)) isn't
16+
// supported in non-GCC modes
17+
assert_false();
18+
#endif
19+
}

regression/cbmc/destructor1/test.desc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
main.c
3+
4+
^\[assert_false.assertion.1\] line 8 assertion 0: FAILURE$
5+
^VERIFICATION FAILED$
6+
^EXIT=10$
7+
^SIGNAL=0$
8+
--
9+
^warning: ignoring

src/ansi-c/ansi_c_entry_point.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,26 @@ bool generate_ansi_c_start_function(
504504

505505
record_function_outputs(symbol, init_code, symbol_table);
506506

507+
// now call destructor functions (a GCC extension)
508+
509+
for(const auto &symbol_table_entry : symbol_table.symbols)
510+
{
511+
const symbolt &symbol = symbol_table_entry.second;
512+
513+
if(symbol.type.id() != ID_code)
514+
continue;
515+
516+
const code_typet &code_type = to_code_type(symbol.type);
517+
if(
518+
code_type.return_type().id() == ID_destructor &&
519+
code_type.parameters().empty())
520+
{
521+
code_function_callt destructor_call(symbol.symbol_expr());
522+
destructor_call.add_source_location() = symbol.location;
523+
init_code.add(std::move(destructor_call));
524+
}
525+
}
526+
507527
// add the entry point symbol
508528
symbolt new_symbol;
509529

0 commit comments

Comments
 (0)