Skip to content

Commit 1e99394

Browse files
committed
Add support for constants in STL function calls
The STL grammar allows the direct use of constants when calling a function. This commit implements this behaviour in order to simplify function calls and to provide a better compatibility to existing STL code.
1 parent 8c4c46e commit 1e99394

File tree

4 files changed

+61
-31
lines changed

4 files changed

+61
-31
lines changed

src/statement-list/parser.y

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1080,7 +1080,7 @@ Oom_Param_Assignment:
10801080
;
10811081

10821082
Param_Assignment:
1083-
Variable_Name TOK_ASSIGNMENT Variable_Access
1083+
Variable_Name TOK_ASSIGNMENT IL_Operand
10841084
{
10851085
newstack($$);
10861086
parser_stack($$) = equal_exprt{std::move(parser_stack($1)),

src/statement-list/statement_list_parse_tree_io.cpp

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Author: Matthias Weiss, [email protected]
1515
#include <util/arith_tools.h>
1616
#include <util/ieee_float.h>
1717

18+
/// String to indicate that there is no value.
1819
#define NO_VALUE "(none)"
1920

2021
/// Prints a constant to the given output stream.
@@ -35,6 +36,21 @@ static void output_constant(std::ostream &out, const constant_exprt &constant)
3536
out << constant.get_value();
3637
}
3738

39+
/// Prints the assignment of a module parameter to the given output stream.
40+
/// \param [out] out: Stream that should receive the result.
41+
/// \param assignment: Assignment that shall be printed.
42+
static void
43+
output_parameter_assignment(std::ostream &out, const equal_exprt &assignment)
44+
{
45+
out << assignment.lhs().get(ID_identifier) << " := ";
46+
const constant_exprt *const constant =
47+
expr_try_dynamic_cast<constant_exprt>(assignment.rhs());
48+
if(constant)
49+
output_constant(out, *constant);
50+
else
51+
out << assignment.rhs().get(ID_identifier);
52+
}
53+
3854
void output_parse_tree(
3955
std::ostream &out,
4056
const statement_list_parse_treet &parse_tree)
@@ -214,9 +230,11 @@ void output_instruction(
214230
out << token.get_statement();
215231
for(const auto &expr : token.operands())
216232
{
217-
if(expr.id() == ID_symbol)
233+
const symbol_exprt *const symbol =
234+
expr_try_dynamic_cast<symbol_exprt>(expr);
235+
if(symbol)
218236
{
219-
out << '\t' << expr.get(ID_identifier);
237+
out << '\t' << symbol->get_identifier();
220238
continue;
221239
}
222240
const constant_exprt *const constant =
@@ -227,14 +245,14 @@ void output_instruction(
227245
output_constant(out, *constant);
228246
continue;
229247
}
230-
const equal_exprt *const eq = expr_try_dynamic_cast<equal_exprt>(expr);
231-
if(eq)
248+
const equal_exprt *const equal = expr_try_dynamic_cast<equal_exprt>(expr);
249+
if(equal)
232250
{
233-
out << "\n\t" << eq->lhs().get(ID_identifier)
234-
<< " := " << eq->rhs().get(ID_identifier);
251+
out << "\n\t";
252+
output_parameter_assignment(out, *equal);
253+
continue;
235254
}
236-
else
237-
out << '\t' << expr.id();
255+
out << '\t' << expr.id();
238256
}
239257
}
240258
}

src/statement-list/statement_list_typecheck.cpp

Lines changed: 25 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1272,11 +1272,8 @@ void statement_list_typecheckt::typecheck_CPROVER_assert(
12721272
expr_try_dynamic_cast<equal_exprt>(op_code.op1());
12731273
if(assignment)
12741274
{
1275-
const symbol_exprt &rhs{to_symbol_expr(assignment->rhs())};
1276-
// Check if identifier is present, create assertion and add it to the
1277-
// function body.
1278-
const exprt op{typecheck_identifier(tia_element, rhs.get_identifier())};
1279-
const code_assertt assertion{op};
1275+
const code_assertt assertion{
1276+
typecheck_function_call_argument_rhs(tia_element, assignment->rhs())};
12801277
tia_element.value.add_to_operands(assertion);
12811278
}
12821279
else
@@ -1294,11 +1291,8 @@ void statement_list_typecheckt::typecheck_CPROVER_assume(
12941291
expr_try_dynamic_cast<equal_exprt>(op_code.op1());
12951292
if(assignment)
12961293
{
1297-
const symbol_exprt &rhs{to_symbol_expr(assignment->rhs())};
1298-
// Check if identifier is present, create assumption and add it to the
1299-
// function body.
1300-
const exprt op{typecheck_identifier(tia_element, rhs.get_identifier())};
1301-
const code_assumet assumption{op};
1294+
const code_assumet assumption{
1295+
typecheck_function_call_argument_rhs(tia_element, assignment->rhs())};
13021296
tia_element.value.add_to_operands(assumption);
13031297
}
13041298
else
@@ -1354,18 +1348,12 @@ void statement_list_typecheckt::typecheck_called_function(
13541348
for(const auto &expr : op_code.operands())
13551349
{
13561350
if(can_cast_expr<equal_exprt>(expr))
1357-
{
1358-
const equal_exprt &assignment{to_equal_expr(expr)};
1359-
assignments.push_back(assignment);
1360-
}
1351+
assignments.push_back(to_equal_expr(expr));
13611352
}
13621353

13631354
for(const code_typet::parametert &param : params)
1364-
{
1365-
const exprt &arg{
1366-
typecheck_function_call_arguments(assignments, param, tia_element)};
1367-
args.push_back(arg);
1368-
}
1355+
args.emplace_back(
1356+
typecheck_function_call_arguments(assignments, param, tia_element));
13691357

13701358
// Check the return value if present.
13711359
if(called_type.return_type().is_nil())
@@ -1404,9 +1392,9 @@ exprt statement_list_typecheckt::typecheck_function_call_arguments(
14041392
const symbol_exprt &lhs{to_symbol_expr(assignment.lhs())};
14051393
if(param_name == lhs.get_identifier())
14061394
{
1407-
const symbol_exprt &rhs{to_symbol_expr(assignment.rhs())};
1408-
const exprt assigned_variable{
1409-
typecheck_identifier(tia_element, rhs.get_identifier())};
1395+
exprt assigned_variable{
1396+
typecheck_function_call_argument_rhs(tia_element, assignment.rhs())};
1397+
14101398
if(param_type == assigned_variable.type())
14111399
return assigned_variable;
14121400
else
@@ -1423,6 +1411,21 @@ exprt statement_list_typecheckt::typecheck_function_call_arguments(
14231411
throw TYPECHECK_ERROR;
14241412
}
14251413

1414+
exprt statement_list_typecheckt::typecheck_function_call_argument_rhs(
1415+
const symbolt &tia_element,
1416+
const exprt &rhs)
1417+
{
1418+
exprt assigned_operand;
1419+
const symbol_exprt *const symbol_rhs =
1420+
expr_try_dynamic_cast<symbol_exprt>(rhs);
1421+
if(symbol_rhs)
1422+
assigned_operand =
1423+
typecheck_identifier(tia_element, symbol_rhs->get_identifier());
1424+
else // constant_exprt.
1425+
assigned_operand = rhs;
1426+
return assigned_operand;
1427+
}
1428+
14261429
exprt statement_list_typecheckt::typecheck_return_value_assignment(
14271430
const std::vector<equal_exprt> &assignments,
14281431
const typet &return_type,

src/statement-list/statement_list_typecheck.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,6 +592,15 @@ class statement_list_typecheckt : public typecheckt
592592
const code_typet::parametert &param,
593593
const symbolt &tia_element);
594594

595+
/// Checks if the given assigned expression is a variable or a constant and
596+
/// returns the typechecked version.
597+
/// \param tia_element: Symbol representation of the TIA element.
598+
/// \param rhs: Expression that the function parameter got assigned to.
599+
/// \return: Expression of either a symbol or a constant.
600+
exprt typecheck_function_call_argument_rhs(
601+
const symbolt &tia_element,
602+
const exprt &rhs);
603+
595604
/// Checks if there is a return value assignment inside of the assignment
596605
/// list of a function call and returns the expression of the assigned
597606
/// variable.

0 commit comments

Comments
 (0)