Skip to content

Commit 8d3017f

Browse files
committed
Linking library functions: support constructor functions
With 7f1cc0f we may remove `__CPROVER_initialize` from the goto model, which in turn made us fail to consider constructors called from it among the set of called functions (as well as any functions (transitively) called from these).
1 parent aaa6d81 commit 8d3017f

File tree

4 files changed

+43
-11
lines changed

4 files changed

+43
-11
lines changed

regression/cbmc/constructor2/main.c

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
#include <assert.h>
2+
#include <stdlib.h>
3+
4+
#ifdef __GNUC__
5+
int x;
6+
7+
__attribute__((constructor)) void init_heap()
8+
{
9+
int *p = malloc(sizeof(int));
10+
free(p);
11+
x = 42;
12+
}
13+
#endif
14+
15+
int main()
16+
{
17+
#ifdef __GNUC__
18+
assert(x == 42);
19+
#endif
20+
return 0;
21+
}
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
CORE
2+
main.c
3+
4+
^EXIT=0$
5+
^SIGNAL=0$
6+
^VERIFICATION SUCCESSFUL$
7+
--
8+
map::at
9+
^warning: ignoring

src/ansi-c/library/stdlib.c

+1
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,7 @@ __CPROVER_HIDE:;
271271

272272
#undef free
273273

274+
void __CPROVER_deallocate(void *);
274275
__CPROVER_bool __VERIFIER_nondet___CPROVER_bool();
275276
#ifndef LIBRARY_CHECK
276277
const void *__CPROVER_alloca_object = 0;

src/goto-programs/link_to_library.cpp

+12-11
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ Author: Daniel Kroening, [email protected]
1919
#include "link_goto_model.h"
2020

2121
/// Try to add \p missing_function from \p library to \p goto_model.
22-
static optionalt<replace_symbolt::expr_mapt> add_one_function(
22+
static std::pair<optionalt<replace_symbolt::expr_mapt>, bool> add_one_function(
2323
goto_modelt &goto_model,
2424
message_handlert &message_handler,
2525
const std::function<void(
@@ -49,6 +49,7 @@ static optionalt<replace_symbolt::expr_mapt> add_one_function(
4949
}
5050

5151
// check whether additional initialization may be required
52+
bool init_required = false;
5253
if(
5354
goto_model.goto_functions.function_map.find(INITIALIZE_FUNCTION) !=
5455
goto_model.goto_functions.function_map.end())
@@ -60,13 +61,15 @@ static optionalt<replace_symbolt::expr_mapt> add_one_function(
6061
!entry.second.is_macro && entry.second.type.id() != ID_code &&
6162
!goto_model.symbol_table.has_symbol(entry.first))
6263
{
63-
goto_model.unload(INITIALIZE_FUNCTION);
64+
init_required = true;
6465
break;
6566
}
6667
}
6768
}
6869

69-
return link_goto_model(goto_model, std::move(library_model), message_handler);
70+
return {
71+
link_goto_model(goto_model, std::move(library_model), message_handler),
72+
init_required};
7073
}
7174

7275
/// Complete missing function definitions using the \p library.
@@ -95,9 +98,7 @@ void link_to_library(
9598
// forward declarations, or perhaps even cases of missing forward
9699
// declarations) may result in type changes to objects.
97100
replace_symbolt::expr_mapt object_type_updates;
98-
const bool had_init =
99-
goto_model.goto_functions.function_map.find(INITIALIZE_FUNCTION) !=
100-
goto_model.goto_functions.function_map.end();
101+
bool need_reinit = false;
101102

102103
while(true)
103104
{
@@ -125,8 +126,10 @@ void link_to_library(
125126
changed = true;
126127
added_functions.insert(id);
127128

128-
auto updates_opt =
129+
auto one_result =
129130
add_one_function(goto_model, message_handler, library, id);
131+
auto updates_opt = one_result.first;
132+
need_reinit |= one_result.second;
130133
if(!updates_opt.has_value())
131134
{
132135
messaget log{message_handler};
@@ -143,11 +146,9 @@ void link_to_library(
143146
break;
144147
}
145148

146-
if(
147-
had_init &&
148-
goto_model.goto_functions.function_map.find(INITIALIZE_FUNCTION) ==
149-
goto_model.goto_functions.function_map.end())
149+
if(need_reinit)
150150
{
151+
goto_model.unload(INITIALIZE_FUNCTION);
151152
static_lifetime_init(
152153
goto_model.symbol_table,
153154
goto_model.symbol_table.lookup_ref(INITIALIZE_FUNCTION).location);

0 commit comments

Comments
 (0)