Skip to content

Commit 0ad55a4

Browse files
committed
Add support for STL return value assignment
Special case for the presence of a return value in the call assignment list.
1 parent 0d5bd73 commit 0ad55a4

File tree

4 files changed

+77
-13
lines changed

4 files changed

+77
-13
lines changed

src/statement-list/statement_list_parser.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ static typet find_return_value(const exprt &root)
8181
for(const exprt &op : root.operands())
8282
{
8383
if(op.get(ID_statement_list_type) == ID_statement_list_return)
84-
return typet(op.id());
84+
return op.type();
8585
}
8686

8787
UNREACHABLE; // Root expression of FC should always have a return value

src/statement-list/statement_list_typecheck.cpp

+60-11
Original file line numberDiff line numberDiff line change
@@ -1262,9 +1262,10 @@ void statement_list_typecheckt::typecheck_called_function(
12621262
symbolt &tia_element)
12631263
{
12641264
const symbol_exprt call_operand{to_symbol_expr(op_code.op0())};
1265-
const symbolt &called_function{
1265+
const symbolt &called_function_sym{
12661266
symbol_table.lookup_ref(call_operand.get_identifier())};
1267-
const code_typet &called_type{to_code_type(called_function.type)};
1267+
const symbol_exprt called_function_expr{called_function_sym.symbol_expr()};
1268+
const code_typet &called_type{to_code_type(called_function_sym.type)};
12681269

12691270
// Check if function name is followed by data block.
12701271
if(!can_cast_expr<equal_exprt>(op_code.op1()))
@@ -1288,11 +1289,22 @@ void statement_list_typecheckt::typecheck_called_function(
12881289

12891290
for(const code_typet::parametert &param : params)
12901291
{
1291-
const exprt &arg{typecheck_function_call_arguments(assignments, param)};
1292+
const exprt &arg{
1293+
typecheck_function_call_arguments(assignments, param, tia_element)};
12921294
args.push_back(arg);
12931295
}
1294-
const code_function_callt call{call_operand, args};
1295-
tia_element.value.add_to_operands(call);
1296+
1297+
// Check the return value if present.
1298+
if(called_type.return_type().is_nil())
1299+
tia_element.value.add_to_operands(
1300+
code_function_callt{called_function_expr, args});
1301+
else
1302+
{
1303+
const exprt lhs{typecheck_return_value_assignment(
1304+
assignments, called_type.return_type(), tia_element)};
1305+
tia_element.value.add_to_operands(
1306+
code_function_callt{lhs, called_function_expr, args});
1307+
}
12961308
}
12971309

12981310
void statement_list_typecheckt::typecheck_called_function_block(
@@ -1309,23 +1321,60 @@ void statement_list_typecheckt::typecheck_called_function_block(
13091321

13101322
exprt statement_list_typecheckt::typecheck_function_call_arguments(
13111323
const std::vector<equal_exprt> &assignments,
1312-
const code_typet::parametert &param)
1324+
const code_typet::parametert &param,
1325+
const symbolt &tia_element)
1326+
{
1327+
const irep_idt &param_name = param.get_base_name();
1328+
const typet &param_type = param.type();
1329+
for(const equal_exprt &assignment : assignments)
1330+
{
1331+
const symbol_exprt &lhs{to_symbol_expr(assignment.lhs())};
1332+
if(param_name == lhs.get_identifier())
1333+
{
1334+
const symbol_exprt &rhs{to_symbol_expr(assignment.rhs())};
1335+
const exprt assigned_variable{
1336+
typecheck_identifier(tia_element, rhs.get_identifier())};
1337+
if(param_type == assigned_variable.type())
1338+
return assigned_variable;
1339+
else
1340+
{
1341+
error() << "Types of parameter assignment do not match: "
1342+
<< param.type().id() << " != " << assigned_variable.type().id()
1343+
<< eom;
1344+
throw TYPECHECK_ERROR;
1345+
}
1346+
}
1347+
}
1348+
error() << "No assignment found for function parameter "
1349+
<< param.get_identifier() << eom;
1350+
throw TYPECHECK_ERROR;
1351+
}
1352+
1353+
exprt statement_list_typecheckt::typecheck_return_value_assignment(
1354+
const std::vector<equal_exprt> &assignments,
1355+
const typet &return_type,
1356+
const symbolt &tia_element)
13131357
{
13141358
for(const equal_exprt &assignment : assignments)
13151359
{
13161360
const symbol_exprt &lhs{to_symbol_expr(assignment.lhs())};
1317-
if(param.get_identifier() == lhs.get_identifier())
1361+
if(ID_statement_list_return_value_id == lhs.get_identifier())
13181362
{
1319-
if(param.type() == assignment.rhs().type())
1320-
return assignment.rhs();
1363+
const symbol_exprt &rhs{to_symbol_expr(assignment.rhs())};
1364+
const exprt assigned_variable{
1365+
typecheck_identifier(tia_element, rhs.get_identifier())};
1366+
if(return_type == assigned_variable.type())
1367+
return assigned_variable;
13211368
else
13221369
{
1323-
error() << "Types of parameter assignment do not match" << eom;
1370+
error() << "Types of return value assignment do not match: "
1371+
<< return_type.id() << " != " << assigned_variable.type().id()
1372+
<< eom;
13241373
throw TYPECHECK_ERROR;
13251374
}
13261375
}
13271376
}
1328-
error() << "No assignment found for function parameter" << eom;
1377+
error() << "No assignment found for function return value" << eom;
13291378
throw TYPECHECK_ERROR;
13301379
}
13311380

src/statement-list/statement_list_typecheck.h

+15-1
Original file line numberDiff line numberDiff line change
@@ -540,10 +540,24 @@ class statement_list_typecheckt : public typecheckt
540540
/// function call and returns the expression of the assigned variable.
541541
/// \param assignments: Assignment list of the function call.
542542
/// \param param: Parameter that should be checked.
543+
/// \param tia_element: Symbol representation of the TIA element.
543544
/// \return: Expression including the assigned symbol's name and type.
544545
exprt typecheck_function_call_arguments(
545546
const std::vector<equal_exprt> &assignments,
546-
const code_typet::parametert &param);
547+
const code_typet::parametert &param,
548+
const symbolt &tia_element);
549+
550+
/// Checks if there is a return value assignment inside of the assignment
551+
/// list of a function call and returns the expression of the assigned
552+
/// variable.
553+
/// \param assignments: Assignment list of the function call.
554+
/// \param return_type: Type of the return value.
555+
/// \param tia_element: Symbol representation of the TIA element.
556+
/// \return: Expression including the assigned symbol's name and type.
557+
exprt typecheck_return_value_assignment(
558+
const std::vector<equal_exprt> &assignments,
559+
const typet &return_type,
560+
const symbolt &tia_element);
547561

548562
// Helper functions
549563

src/util/irep_ids.def

+1
Original file line numberDiff line numberDiff line change
@@ -774,6 +774,7 @@ IREP_ID_ONE(statement_list_var_constant)
774774
IREP_ID_ONE(statement_list_var_temp)
775775
IREP_ID_ONE(statement_list_var_static)
776776
IREP_ID_ONE(statement_list_return)
777+
IREP_ID_TWO(statement_list_return_value_id, Ret_Val)
777778
IREP_ID_ONE(statement_list_var_entry)
778779
IREP_ID_ONE(statement_list_var_decls)
779780
IREP_ID_ONE(statement_list_network)

0 commit comments

Comments
 (0)