Skip to content

Commit b93a666

Browse files
author
Daniel Kroening
committed
pull out code for static initialisation
Refactoring, reduces the size of a function
1 parent 048caed commit b93a666

File tree

1 file changed

+80
-75
lines changed

1 file changed

+80
-75
lines changed

src/linking/static_lifetime_init.cpp

Lines changed: 80 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,83 @@ Author: Daniel Kroening, [email protected]
2222

2323
#include <goto-programs/goto_functions.h>
2424

25+
static optionalt<codet>
26+
static_lifetime_init(const irep_idt &identifier, symbol_tablet &symbol_table)
27+
{
28+
const namespacet ns(symbol_table);
29+
const symbolt &symbol = ns.lookup(identifier);
30+
31+
if(!symbol.is_static_lifetime)
32+
return {};
33+
34+
if(symbol.is_type || symbol.is_macro)
35+
return {};
36+
37+
// special values
38+
if(
39+
identifier == CPROVER_PREFIX "constant_infinity_uint" ||
40+
identifier == CPROVER_PREFIX "memory" || identifier == "__func__" ||
41+
identifier == "__FUNCTION__" || identifier == "__PRETTY_FUNCTION__" ||
42+
identifier == "argc'" || identifier == "argv'" || identifier == "envp'" ||
43+
identifier == "envp_size'")
44+
return {};
45+
46+
// just for linking
47+
if(has_prefix(id2string(identifier), CPROVER_PREFIX "architecture_"))
48+
return {};
49+
50+
const typet &type = ns.follow(symbol.type);
51+
52+
// check type
53+
if(type.id() == ID_code || type.id() == ID_empty)
54+
return {};
55+
56+
// We won't try to initialize any symbols that have
57+
// remained incomplete.
58+
59+
if(symbol.value.is_nil() && symbol.is_extern)
60+
// Compilers would usually complain about these
61+
// symbols being undefined.
62+
return {};
63+
64+
if(type.id() == ID_array && to_array_type(type).size().is_nil())
65+
{
66+
// C standard 6.9.2, paragraph 5
67+
// adjust the type to an array of size 1
68+
symbolt &writable_symbol = *symbol_table.get_writeable(identifier);
69+
writable_symbol.type = type;
70+
writable_symbol.type.set(ID_size, from_integer(1, size_type()));
71+
}
72+
73+
if(
74+
(type.id() == ID_struct || type.id() == ID_union) &&
75+
to_struct_union_type(type).is_incomplete())
76+
{
77+
return {}; // do not initialize
78+
}
79+
80+
if(symbol.value.id() == ID_nondet)
81+
{
82+
return {}; // do not initialize
83+
}
84+
85+
exprt rhs;
86+
87+
if(symbol.value.is_nil())
88+
{
89+
const auto zero = zero_initializer(symbol.type, symbol.location, ns);
90+
CHECK_RETURN(zero.has_value());
91+
rhs = *zero;
92+
}
93+
else
94+
rhs = symbol.value;
95+
96+
code_assignt code(symbol.symbol_expr(), rhs);
97+
code.add_source_location() = symbol.location;
98+
99+
return std::move(code);
100+
}
101+
25102
void static_lifetime_init(
26103
symbol_tablet &symbol_table,
27104
const source_locationt &source_location)
@@ -52,81 +129,9 @@ void static_lifetime_init(
52129

53130
for(const std::string &id : symbols)
54131
{
55-
const symbolt &symbol=ns.lookup(id);
56-
57-
const irep_idt &identifier=symbol.name;
58-
59-
if(!symbol.is_static_lifetime)
60-
continue;
61-
62-
if(symbol.is_type || symbol.is_macro)
63-
continue;
64-
65-
// special values
66-
if(identifier==CPROVER_PREFIX "constant_infinity_uint" ||
67-
identifier==CPROVER_PREFIX "memory" ||
68-
identifier=="__func__" ||
69-
identifier=="__FUNCTION__" ||
70-
identifier=="__PRETTY_FUNCTION__" ||
71-
identifier=="argc'" ||
72-
identifier=="argv'" ||
73-
identifier=="envp'" ||
74-
identifier=="envp_size'")
75-
continue;
76-
77-
// just for linking
78-
if(has_prefix(id, CPROVER_PREFIX "architecture_"))
79-
continue;
80-
81-
const typet &type=ns.follow(symbol.type);
82-
83-
// check type
84-
if(type.id()==ID_code ||
85-
type.id()==ID_empty)
86-
continue;
87-
88-
// We won't try to initialize any symbols that have
89-
// remained incomplete.
90-
91-
if(symbol.value.is_nil() &&
92-
symbol.is_extern)
93-
// Compilers would usually complain about these
94-
// symbols being undefined.
95-
continue;
96-
97-
if(type.id()==ID_array &&
98-
to_array_type(type).size().is_nil())
99-
{
100-
// C standard 6.9.2, paragraph 5
101-
// adjust the type to an array of size 1
102-
symbolt &writable_symbol = *symbol_table.get_writeable(identifier);
103-
writable_symbol.type = type;
104-
writable_symbol.type.set(ID_size, from_integer(1, size_type()));
105-
}
106-
107-
if(
108-
(type.id() == ID_struct || type.id() == ID_union) &&
109-
to_struct_union_type(type).is_incomplete())
110-
continue; // do not initialize
111-
112-
if(symbol.value.id()==ID_nondet)
113-
continue; // do not initialize
114-
115-
exprt rhs;
116-
117-
if(symbol.value.is_nil())
118-
{
119-
const auto zero = zero_initializer(symbol.type, symbol.location, ns);
120-
CHECK_RETURN(zero.has_value());
121-
rhs = *zero;
122-
}
123-
else
124-
rhs=symbol.value;
125-
126-
code_assignt code(symbol.symbol_expr(), rhs);
127-
code.add_source_location()=symbol.location;
128-
129-
dest.add(code);
132+
auto code = static_lifetime_init(id, symbol_table);
133+
if(code.has_value())
134+
dest.add(std::move(*code));
130135
}
131136

132137
// call designated "initialization" functions

0 commit comments

Comments
 (0)