Skip to content

Commit 47a3277

Browse files
committed
introduce code_frontend_returnt
This splits the classes that represent return statements in the frontends and the return instructions in goto instructions. They differ in semantics and in the invariants that they maintain. The goto instruction variant always has a return value. The constructors for creating that class without return value are removed.
1 parent 60c9fe5 commit 47a3277

20 files changed

+107
-81
lines changed

jbmc/src/java_bytecode/create_array_with_type_intrinsic.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ codet create_array_with_type_body(
105105
new_array_element_classid, old_array_element_classid));
106106

107107
// return new_array
108-
code_block.add(code_returnt(new_array_symbol_expr));
108+
code_block.add(code_frontend_returnt(new_array_symbol_expr));
109109

110110
return std::move(code_block);
111111
}

jbmc/src/java_bytecode/java_bytecode_convert_method.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1361,7 +1361,7 @@ java_bytecode_convert_methodt::convert_instructions(const methodt &method)
13611361
else if(bytecode == BC_return)
13621362
{
13631363
PRECONDITION(op.empty() && results.empty());
1364-
c=code_returnt();
1364+
c = code_frontend_returnt();
13651365
}
13661366
else if(bytecode == patternt("?return"))
13671367
{
@@ -1370,7 +1370,7 @@ java_bytecode_convert_methodt::convert_instructions(const methodt &method)
13701370
PRECONDITION(op.size() == 1 && results.empty());
13711371
const exprt r =
13721372
typecast_exprt::conditional_cast(op[0], method_return_type);
1373-
c=code_returnt(r);
1373+
c = code_frontend_returnt(r);
13741374
}
13751375
else if(bytecode == patternt("?astore"))
13761376
{

jbmc/src/java_bytecode/java_static_initializers.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ code_blockt get_thread_safe_clinit_wrapper_body(
590590
gen_clinit_eqexpr(
591591
clinit_thread_local_state_sym.symbol_expr(),
592592
clinit_statest::INIT_COMPLETE),
593-
code_returnt());
593+
code_frontend_returnt());
594594
function_body.add(std::move(conditional));
595595
}
596596

@@ -651,7 +651,8 @@ code_blockt get_thread_safe_clinit_wrapper_body(
651651

652652
// if(init_complete) return;
653653
{
654-
code_ifthenelset conditional(init_complete.symbol_expr(), code_returnt());
654+
code_ifthenelset conditional(
655+
init_complete.symbol_expr(), code_frontend_returnt());
655656
function_body.add(std::move(conditional));
656657
}
657658

@@ -696,7 +697,7 @@ code_blockt get_thread_safe_clinit_wrapper_body(
696697
gen_clinit_assign(
697698
clinit_state_sym.symbol_expr(), clinit_statest::INIT_COMPLETE));
698699
function_body.add(atomic_end);
699-
function_body.add(code_returnt());
700+
function_body.add(code_frontend_returnt());
700701
}
701702

702703
return function_body;

src/ansi-c/c_typecheck_base.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ class c_typecheck_baset:
139139
virtual void typecheck_gcc_computed_goto(codet &code);
140140
virtual void typecheck_gcc_switch_case_range(code_gcc_switch_case_ranget &);
141141
virtual void typecheck_gcc_local_label(codet &code);
142-
virtual void typecheck_return(code_returnt &code);
142+
virtual void typecheck_return(code_frontend_returnt &);
143143
virtual void typecheck_switch(codet &code);
144144
virtual void typecheck_while(code_whilet &code);
145145
virtual void typecheck_dowhile(code_dowhilet &code);

src/ansi-c/c_typecheck_code.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ void c_typecheck_baset::typecheck_code(codet &code)
6868
else if(statement==ID_continue)
6969
typecheck_continue(code);
7070
else if(statement==ID_return)
71-
typecheck_return(to_code_return(code));
71+
typecheck_return(to_code_frontend_return(code));
7272
else if(statement==ID_decl)
7373
typecheck_decl(code);
7474
else if(statement==ID_assign)
@@ -643,7 +643,7 @@ void c_typecheck_baset::typecheck_start_thread(codet &code)
643643
typecheck_code(to_code(code.op0()));
644644
}
645645

646-
void c_typecheck_baset::typecheck_return(code_returnt &code)
646+
void c_typecheck_baset::typecheck_return(code_frontend_returnt &code)
647647
{
648648
if(code.has_return_value())
649649
{

src/ansi-c/expr2c.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2680,7 +2680,7 @@ std::string expr2ct::convert_code_return(
26802680
std::string dest=indent_str(indent);
26812681
dest+="return";
26822682

2683-
if(to_code_return(src).has_return_value())
2683+
if(to_code_frontend_return(src).has_return_value())
26842684
dest+=" "+convert(src.op0());
26852685

26862686
dest+=';';

src/cpp/cpp_typecheck_compound_type.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -688,8 +688,8 @@ void cpp_typecheckt::typecheck_compound_declarator(
688688
{
689689
expr_call.type()=to_code_type(component.type()).return_type();
690690

691-
func_symb.value = code_blockt{
692-
{code_returnt(already_typechecked_exprt{std::move(expr_call)})}};
691+
func_symb.value = code_blockt{{code_frontend_returnt(
692+
already_typechecked_exprt{std::move(expr_call)})}};
693693
}
694694
else
695695
{

src/cpp/parse.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7350,7 +7350,7 @@ optionalt<codet> Parser::rStatement()
73507350

73517351
lex.get_token(tk1);
73527352

7353-
code_returnt statement;
7353+
code_frontend_returnt statement;
73547354
set_location(statement, tk1);
73557355

73567356
if(lex.LookAhead(0)==';')

src/goto-harness/recursive_initialization.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ code_blockt build_null_pointer(const symbol_exprt &result_symbol)
239239
const null_pointer_exprt nullptr_expr{to_pointer_type(type_to_construct)};
240240
const code_assignt assign_null{dereference_exprt{result_symbol},
241241
nullptr_expr};
242-
return code_blockt{{assign_null, code_returnt{}}};
242+
return code_blockt{{assign_null, code_frontend_returnt{}}};
243243
}
244244

245245
code_blockt recursive_initializationt::build_constructor_body(
@@ -688,7 +688,7 @@ code_blockt recursive_initializationt::build_pointer_constructor(
688688

689689
null_pointer_exprt nullptr_expr{pointer_type(type.subtype())};
690690
const code_assignt assign_null{dereference_exprt{result}, nullptr_expr};
691-
code_blockt null_and_return{{assign_null, code_returnt{}}};
691+
code_blockt null_and_return{{assign_null, code_frontend_returnt{}}};
692692
body.add(code_ifthenelset{conjunction(should_not_recurse), null_and_return});
693693

694694
const auto should_recurse_nondet =
@@ -1034,7 +1034,7 @@ code_blockt recursive_initializationt::build_function_pointer_constructor(
10341034
auto const condition = equal_exprt{
10351035
function_pointer_selector,
10361036
from_integer(function_pointer_index, function_pointer_selector.type())};
1037-
auto const then = code_blockt{{assign, code_returnt{}}};
1037+
auto const then = code_blockt{{assign, code_frontend_returnt{}}};
10381038
body.add(code_ifthenelset{condition, then});
10391039
}
10401040
else

src/goto-instrument/contracts/contracts.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1074,7 +1074,7 @@ void code_contractst::add_contract_check(
10741074
replace_symbolt common_replace;
10751075

10761076
// decl ret
1077-
code_returnt return_stmt;
1077+
optionalt<code_returnt> return_stmt;
10781078
if(code_type.return_type() != empty_typet())
10791079
{
10801080
symbol_exprt r = new_tmp_symbol(
@@ -1178,7 +1178,8 @@ void code_contractst::add_contract_check(
11781178

11791179
if(code_type.return_type() != empty_typet())
11801180
{
1181-
check.add(goto_programt::make_return(return_stmt, skip->source_location()));
1181+
check.add(
1182+
goto_programt::make_return(return_stmt.value(), skip->source_location()));
11821183
}
11831184

11841185
// prepend the new code to dest

src/goto-programs/goto_convert.cpp

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ void goto_convertt::convert(
470470
else if(statement==ID_break)
471471
convert_break(to_code_break(code), dest, mode);
472472
else if(statement==ID_return)
473-
convert_return(to_code_return(code), dest, mode);
473+
convert_return(to_code_frontend_return(code), dest, mode);
474474
else if(statement==ID_continue)
475475
convert_continue(to_code_continue(code), dest, mode);
476476
else if(statement==ID_goto)
@@ -1258,7 +1258,7 @@ void goto_convertt::convert_break(
12581258
}
12591259

12601260
void goto_convertt::convert_return(
1261-
const code_returnt &code,
1261+
const code_frontend_returnt &code,
12621262
goto_programt &dest,
12631263
const irep_idt &mode)
12641264
{
@@ -1273,7 +1273,7 @@ void goto_convertt::convert_return(
12731273
"return takes none or one operand",
12741274
code.find_source_location());
12751275

1276-
code_returnt new_code(code);
1276+
code_frontend_returnt new_code(code);
12771277

12781278
if(new_code.has_return_value())
12791279
{
@@ -1297,7 +1297,8 @@ void goto_convertt::convert_return(
12971297
new_code.find_source_location());
12981298

12991299
// Now add a return node to set the return value.
1300-
dest.add(goto_programt::make_return(new_code, new_code.source_location()));
1300+
dest.add(goto_programt::make_return(
1301+
to_code_return(new_code), new_code.source_location()));
13011302
}
13021303
else
13031304
{

src/goto-programs/goto_convert_class.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -267,7 +267,7 @@ class goto_convertt:public messaget
267267
goto_programt &dest,
268268
const irep_idt &mode);
269269
void convert_return(
270-
const code_returnt &code,
270+
const code_frontend_returnt &,
271271
goto_programt &dest,
272272
const irep_idt &mode);
273273
void convert_continue(

src/jsil/jsil_parse_tree.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ void jsil_declarationt::to_symbol(symbolt &symbol) const
6666
static_cast<const codet&>(find(ID_value))));
6767

6868
irept returns(find(ID_return));
69-
code_returnt r(symbol_exprt::typeless(returns.get(ID_value)));
69+
code_frontend_returnt r(symbol_exprt::typeless(returns.get(ID_value)));
7070

7171
irept throws(find(ID_throw));
7272
side_effect_expr_throwt t(

src/jsil/jsil_typecheck.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ void jsil_typecheckt::typecheck_code(codet &code)
637637
if(statement==ID_function_call)
638638
typecheck_function_call(to_code_function_call(code));
639639
else if(statement==ID_return)
640-
typecheck_return(to_code_return(code));
640+
typecheck_return(to_code_frontend_return(code));
641641
else if(statement==ID_expression)
642642
{
643643
if(code.operands().size()!=1)
@@ -678,7 +678,7 @@ void jsil_typecheckt::typecheck_code(codet &code)
678678
}
679679
}
680680

681-
void jsil_typecheckt::typecheck_return(code_returnt &code)
681+
void jsil_typecheckt::typecheck_return(code_frontend_returnt &code)
682682
{
683683
if(code.has_return_value())
684684
typecheck_expr(code.return_value());

src/jsil/jsil_typecheck.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Author: Michael Tautschnig, [email protected]
2020
class code_assignt;
2121
class code_function_callt;
2222
class code_ifthenelset;
23-
class code_returnt;
23+
class code_frontend_returnt;
2424
class code_try_catcht;
2525
class codet;
2626
class message_handlert;
@@ -89,7 +89,7 @@ class jsil_typecheckt:public typecheckt
8989
void typecheck_expr_main(exprt &expr);
9090
void typecheck_code(codet &code);
9191
void typecheck_function_call(code_function_callt &function_call);
92-
void typecheck_return(code_returnt &code);
92+
void typecheck_return(code_frontend_returnt &);
9393
void typecheck_block(codet &code);
9494
void typecheck_ifthenelse(code_ifthenelset &code);
9595
void typecheck_assign(code_assignt &code);

src/pointer-analysis/value_set.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1582,12 +1582,9 @@ void value_sett::apply_code_rec(
15821582
{
15831583
const code_returnt &code_return = to_code_return(code);
15841584
// this is turned into an assignment
1585-
if(code_return.has_return_value())
1586-
{
1587-
symbol_exprt lhs(
1588-
"value_set::return_value", code_return.return_value().type());
1589-
assign(lhs, code_return.return_value(), ns, false, false);
1590-
}
1585+
symbol_exprt lhs(
1586+
"value_set::return_value", code_return.return_value().type());
1587+
assign(lhs, code_return.return_value(), ns, false, false);
15911588
}
15921589
else if(statement==ID_array_set)
15931590
{

src/pointer-analysis/value_set_fi.cpp

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,12 +1378,9 @@ void value_set_fit::apply_code(const codet &code, const namespacet &ns)
13781378
{
13791379
const code_returnt &code_return = to_code_return(code);
13801380
// this is turned into an assignment
1381-
if(code_return.has_return_value())
1382-
{
1383-
std::string rvs="value_set::return_value"+std::to_string(from_function);
1384-
symbol_exprt lhs(rvs, code_return.return_value().type());
1385-
assign(lhs, code_return.return_value(), ns);
1386-
}
1381+
std::string rvs = "value_set::return_value" + std::to_string(from_function);
1382+
symbol_exprt lhs(rvs, code_return.return_value().type());
1383+
assign(lhs, code_return.return_value(), ns);
13871384
}
13881385
else if(statement==ID_fence)
13891386
{

src/util/goto_instruction_code.h

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,4 +479,61 @@ inline void validate_expr(const code_outputt &output)
479479
code_outputt::check(output);
480480
}
481481

482+
/// \ref codet representation of a "return from a function" statement.
483+
class code_returnt : public codet
484+
{
485+
public:
486+
explicit code_returnt(exprt _op) : codet(ID_return, {std::move(_op)})
487+
{
488+
}
489+
490+
const exprt &return_value() const
491+
{
492+
return op0();
493+
}
494+
495+
exprt &return_value()
496+
{
497+
return op0();
498+
}
499+
500+
static void check(
501+
const codet &code,
502+
const validation_modet vm = validation_modet::INVARIANT)
503+
{
504+
DATA_CHECK(vm, code.operands().size() == 1, "return must have one operand");
505+
}
506+
507+
protected:
508+
using codet::op0;
509+
using codet::op1;
510+
using codet::op2;
511+
using codet::op3;
512+
};
513+
514+
template <>
515+
inline bool can_cast_expr<code_returnt>(const exprt &base)
516+
{
517+
return detail::can_cast_code_impl(base, ID_return);
518+
}
519+
520+
inline void validate_expr(const code_returnt &x)
521+
{
522+
code_returnt::check(x);
523+
}
524+
525+
inline const code_returnt &to_code_return(const codet &code)
526+
{
527+
PRECONDITION(code.get_statement() == ID_return);
528+
code_returnt::check(code);
529+
return static_cast<const code_returnt &>(code);
530+
}
531+
532+
inline code_returnt &to_code_return(codet &code)
533+
{
534+
PRECONDITION(code.get_statement() == ID_return);
535+
code_returnt::check(code);
536+
return static_cast<code_returnt &>(code);
537+
}
538+
482539
#endif // CPROVER_GOTO_PROGRAMS_GOTO_INSTRUCTION_CODE_H

src/util/std_code.h

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -902,14 +902,14 @@ inline code_gotot &to_code_goto(codet &code)
902902
}
903903

904904
/// \ref codet representation of a "return from a function" statement.
905-
class code_returnt:public codet
905+
class code_frontend_returnt : public codet
906906
{
907907
public:
908-
code_returnt() : codet(ID_return, {nil_exprt()})
908+
code_frontend_returnt() : codet(ID_return, {nil_exprt()})
909909
{
910910
}
911911

912-
explicit code_returnt(exprt _op) : codet(ID_return, {std::move(_op)})
912+
explicit code_frontend_returnt(exprt _op) : codet(ID_return, {std::move(_op)})
913913
{
914914
}
915915

@@ -942,28 +942,29 @@ class code_returnt:public codet
942942
using codet::op3;
943943
};
944944

945-
template<> inline bool can_cast_expr<code_returnt>(const exprt &base)
945+
template <>
946+
inline bool can_cast_expr<code_frontend_returnt>(const exprt &base)
946947
{
947948
return detail::can_cast_code_impl(base, ID_return);
948949
}
949950

950-
inline void validate_expr(const code_returnt &x)
951+
inline void validate_expr(const code_frontend_returnt &x)
951952
{
952-
code_returnt::check(x);
953+
code_frontend_returnt::check(x);
953954
}
954955

955-
inline const code_returnt &to_code_return(const codet &code)
956+
inline const code_frontend_returnt &to_code_frontend_return(const codet &code)
956957
{
957958
PRECONDITION(code.get_statement() == ID_return);
958-
code_returnt::check(code);
959-
return static_cast<const code_returnt &>(code);
959+
code_frontend_returnt::check(code);
960+
return static_cast<const code_frontend_returnt &>(code);
960961
}
961962

962-
inline code_returnt &to_code_return(codet &code)
963+
inline code_frontend_returnt &to_code_frontend_return(codet &code)
963964
{
964965
PRECONDITION(code.get_statement() == ID_return);
965-
code_returnt::check(code);
966-
return static_cast<code_returnt &>(code);
966+
code_frontend_returnt::check(code);
967+
return static_cast<code_frontend_returnt &>(code);
967968
}
968969

969970
/// \ref codet representation of a label for branch targets.

0 commit comments

Comments
 (0)