Skip to content

Commit d71ebe4

Browse files
committed
Do not read from goto_functiont::type
Future changes will remove this member as it is redundant with the information stored in the symbol table. We keep writing to it so as not to break any users, but no longer read it.
1 parent d18a463 commit d71ebe4

12 files changed

+68
-36
lines changed

src/goto-checker/symex_coverage.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ goto_program_coverage_recordt::goto_program_coverage_recordt(
161161
xml.set_attribute("name", id2string(gf_it->first));
162162

163163
xml.set_attribute(
164-
"signature", from_type(ns, gf_it->first, gf_it->second.type));
164+
"signature", from_type(ns, gf_it->first, ns.lookup(gf_it->first).type));
165165

166166
xml.set_attribute("line-rate", rate_detailed(lines_covered, lines_total));
167167
xml.set_attribute("branch-rate", rate(branches_covered, branches_total));

src/goto-instrument/code_contracts.cpp

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -484,8 +484,8 @@ void code_contractst::instrument_call_statement(
484484
return;
485485
}
486486

487-
exprt called_assigns = static_cast<const exprt &>(
488-
called_func->second.type.find(ID_C_spec_assigns));
487+
exprt called_assigns =
488+
static_cast<const exprt &>(called_sym.type.find(ID_C_spec_assigns));
489489
if(called_assigns.is_nil()) // Called function has no assigns clause
490490
{
491491
// Fail if called function has no assigns clause.
@@ -763,18 +763,15 @@ void code_contractst::add_contract_check(
763763
{
764764
PRECONDITION(!dest.instructions.empty());
765765

766-
goto_functionst::function_mapt::iterator f_it =
767-
goto_functions.function_map.find(mangled_fun);
768-
PRECONDITION(f_it != goto_functions.function_map.end());
769-
770-
const goto_functionst::goto_functiont &gf = f_it->second;
766+
const symbolt &function_symbol = ns.lookup(mangled_fun);
767+
const code_typet &code_type = to_code_type(function_symbol.type);
771768

772769
const exprt &assigns =
773-
static_cast<const exprt &>(gf.type.find(ID_C_spec_assigns));
770+
static_cast<const exprt &>(code_type.find(ID_C_spec_assigns));
774771
const exprt &requires =
775-
static_cast<const exprt &>(gf.type.find(ID_C_spec_requires));
772+
static_cast<const exprt &>(code_type.find(ID_C_spec_requires));
776773
const exprt &ensures =
777-
static_cast<const exprt &>(gf.type.find(ID_C_spec_ensures));
774+
static_cast<const exprt &>(code_type.find(ID_C_spec_ensures));
778775
INVARIANT(
779776
ensures.is_not_nil() || assigns.is_not_nil(),
780777
"Code contract enforcement is trivial without an ensures or assigns "
@@ -803,15 +800,14 @@ void code_contractst::add_contract_check(
803800
skip->source_location));
804801

805802
// prepare function call including all declarations
806-
const symbolt &function_symbol = ns.lookup(mangled_fun);
807803
code_function_callt call(function_symbol.symbol_expr());
808804
replace_symbolt replace;
809805

810806
// decl ret
811-
if(gf.type.return_type()!=empty_typet())
807+
if(code_type.return_type() != empty_typet())
812808
{
813809
symbol_exprt r = new_tmp_symbol(
814-
gf.type.return_type(),
810+
code_type.return_type(),
815811
skip->source_location,
816812
wrapper_fun,
817813
function_symbol.mode)
@@ -825,6 +821,11 @@ void code_contractst::add_contract_check(
825821
}
826822

827823
// decl parameter1 ...
824+
goto_functionst::function_mapt::iterator f_it =
825+
goto_functions.function_map.find(mangled_fun);
826+
PRECONDITION(f_it != goto_functions.function_map.end());
827+
828+
const goto_functionst::goto_functiont &gf = f_it->second;
828829
for(const auto &parameter : gf.parameter_identifiers)
829830
{
830831
PRECONDITION(!parameter.empty());

src/goto-instrument/generate_function_bodies.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -321,9 +321,10 @@ class havoc_generate_function_bodiest : public generate_function_bodiest
321321
function.body.destructive_append(dest);
322322
}
323323

324-
if(function.type.return_type() != empty_typet())
324+
const typet &return_type = to_code_type(function_symbol.type).return_type();
325+
if(return_type != empty_typet())
325326
{
326-
typet type(function.type.return_type());
327+
typet type(return_type);
327328
type.remove(ID_C_constant);
328329

329330
symbolt &aux_symbol = get_fresh_aux_symbol(
@@ -350,8 +351,8 @@ class havoc_generate_function_bodiest : public generate_function_bodiest
350351

351352
function.body.destructive_append(dest);
352353

353-
exprt return_expr = typecast_exprt::conditional_cast(
354-
aux_symbol.symbol_expr(), function.type.return_type());
354+
exprt return_expr =
355+
typecast_exprt::conditional_cast(aux_symbol.symbol_expr(), return_type);
355356

356357
add_instruction(goto_programt::make_return(code_returnt(return_expr)));
357358

src/goto-instrument/replace_calls.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ void replace_callst::operator()(
9797
PRECONDITION(base_type_eq(f_it1->second.type, f_it2->second.type, ns));
9898

9999
// check that returns have not been removed
100-
if(to_code_type(f_it1->second.type).return_type().id() != ID_empty)
100+
if(to_code_type(function.type()).return_type().id() != ID_empty)
101101
{
102102
goto_programt::const_targett next_it = std::next(it);
103103
if(next_it != goto_program.instructions.end() && next_it->is_assign())
@@ -112,7 +112,7 @@ void replace_callst::operator()(
112112
}
113113

114114
// Finally modify the call
115-
function.type() = f_it2->second.type;
115+
function.type() = ns.lookup(f_it2->first).type;
116116
se.set_identifier(new_id);
117117

118118
ins.set_function_call(cfc);
@@ -167,7 +167,8 @@ void replace_callst::check_replacement_map(
167167
auto it1 = goto_functions.function_map.find(p.first);
168168
if(it1 != goto_functions.function_map.end())
169169
{
170-
if(!base_type_eq(it1->second.type, it2->second.type, ns))
170+
if(!base_type_eq(
171+
ns.lookup(it1->first).type, ns.lookup(it2->first).type, ns))
171172
throw invalid_command_line_argument_exceptiont(
172173
"functions " + id2string(p.first) + " and " + id2string(p.second) +
173174
" are not type-compatible",

src/goto-programs/goto_convert_functions.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ bool goto_convert_functionst::hide(const goto_programt &goto_program)
8787

8888
void goto_convert_functionst::add_return(
8989
goto_functionst::goto_functiont &f,
90+
const typet &return_type,
9091
const source_locationt &source_location)
9192
{
9293
#if 0
@@ -133,7 +134,7 @@ void goto_convert_functionst::add_return(
133134

134135
#endif
135136

136-
side_effect_expr_nondett rhs(f.type.return_type(), source_location);
137+
side_effect_expr_nondett rhs(return_type, source_location);
137138

138139
f.body.add(
139140
goto_programt::make_return(code_returnt(std::move(rhs)), source_location));
@@ -190,15 +191,15 @@ void goto_convert_functionst::convert_function(
190191

191192
targets = targetst();
192193
targets.set_return(end_function);
193-
targets.has_return_value = f.type.return_type().id() != ID_empty &&
194-
f.type.return_type().id() != ID_constructor &&
195-
f.type.return_type().id() != ID_destructor;
194+
targets.has_return_value = code_type.return_type().id() != ID_empty &&
195+
code_type.return_type().id() != ID_constructor &&
196+
code_type.return_type().id() != ID_destructor;
196197

197198
goto_convert_rec(code, f.body, mode);
198199

199200
// add non-det return value, if needed
200201
if(targets.has_return_value)
201-
add_return(f, end_location);
202+
add_return(f, code_type.return_type(), end_location);
202203

203204
// handle SV-COMP's __VERIFIER_atomic_
204205
if(

src/goto-programs/goto_convert_functions.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ class goto_convert_functionst:public goto_convertt
5858
//
5959
void add_return(
6060
goto_functionst::goto_functiont &,
61+
const typet &return_type,
6162
const source_locationt &);
6263
};
6364

src/goto-programs/goto_functions.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,5 +137,17 @@ void goto_functionst::validate(const namespacet &ns, const validation_modet vm)
137137
}
138138

139139
goto_function.validate(ns, vm);
140+
141+
// Check that a void function does not contain any RETURN instructions
142+
if(to_code_type(function_symbol.type).return_type().id() == ID_empty)
143+
{
144+
forall_goto_program_instructions(instruction, goto_function.body)
145+
{
146+
DATA_CHECK(
147+
vm,
148+
!instruction->is_return(),
149+
"void function should not return a value");
150+
}
151+
}
140152
}
141153
}

src/goto-programs/link_goto_model.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ static bool link_functions(
100100
in_dest_symbol_table.parameter_identifiers.swap(
101101
src_func.parameter_identifiers);
102102
in_dest_symbol_table.type=src_func.type;
103+
// the linking code will have ensured that types match
104+
INVARIANT(
105+
base_type_eq(
106+
dest_symbol_table.lookup_ref(final_id).type, src_func.type, ns),
107+
"linking ensures that types match");
103108
}
104109
else if(src_func.body.instructions.empty() ||
105110
src_ns.lookup(src_it->first).is_weak)

src/goto-programs/remove_function_pointers.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ remove_function_pointerst::remove_function_pointerst(
125125

126126
// build type map
127127
forall_goto_functions(f_it, goto_functions)
128-
type_map.emplace(f_it->first, f_it->second.type);
128+
type_map.emplace(f_it->first, to_code_type(ns.lookup(f_it->first).type));
129129
}
130130

131131
bool remove_function_pointerst::arg_is_type_compatible(

src/goto-programs/remove_returns.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,11 @@ void remove_returnst::replace_returns(
101101
const irep_idt &function_id,
102102
goto_functionst::goto_functiont &function)
103103
{
104-
typet return_type = function.type.return_type();
104+
// look up the function symbol
105+
symbolt &function_symbol = *symbol_table.get_writeable(function_id);
105106

106107
// returns something but void?
107-
if(return_type == empty_typet())
108+
if(to_code_type(function_symbol.type).return_type() == empty_typet())
108109
return;
109110

110111
// add return_value symbol to symbol_table, if not already created:

src/goto-symex/symex_function_call.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,8 +42,6 @@ void goto_symext::parameter_assignments(
4242
statet &state,
4343
const exprt::operandst &arguments)
4444
{
45-
const code_typet &function_type=goto_function.type;
46-
4745
// iterates over the arguments
4846
exprt::operandst::const_iterator it1=arguments.begin();
4947

@@ -151,7 +149,7 @@ void goto_symext::parameter_assignments(
151149
it1++;
152150
}
153151

154-
if(function_type.has_ellipsis())
152+
if(to_code_type(ns.lookup(function_identifier).type).has_ellipsis())
155153
{
156154
// These are va_arg arguments; their types may differ from call to call
157155
for(; it1 != arguments.end(); it1++)

unit/goto-programs/remove_returns.cpp

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,22 @@ TEST_CASE(
4848
{
4949
symbol_tablet symbol_table;
5050
goto_functionst goto_functions;
51+
52+
symbolt foo_function_symbol;
53+
foo_function_symbol.name = "foo_function";
54+
foo_function_symbol.type = code_typet{{}, empty_typet{}};
55+
symbol_table.insert(foo_function_symbol);
56+
57+
symbolt bar_function_symbol;
58+
bar_function_symbol.name = "bar_function";
59+
bar_function_symbol.type = code_typet{{}, signedbv_typet{32}};
60+
symbol_table.insert(bar_function_symbol);
61+
5162
*goto_functions.function_map["foo_function"].body.add_instruction() =
52-
goto_programt::make_function_call(code_function_callt{
53-
symbol_exprt{"local_variable", signedbv_typet{32}},
54-
symbol_exprt{"bar_function", code_typet{{}, signedbv_typet{32}}},
55-
{}});
63+
goto_programt::make_function_call(
64+
code_function_callt{symbol_exprt{"local_variable", signedbv_typet{32}},
65+
bar_function_symbol.symbol_expr(),
66+
{}});
5667
const cbmc_invariants_should_throwt invariants_throw;
5768
REQUIRE_THROWS_MATCHES(
5869
remove_returns(symbol_table, goto_functions),

0 commit comments

Comments
 (0)