Skip to content

Commit ecd884a

Browse files
committed
Fix edge case for STL bit string termination
Since the RLO is only modeled implicitly, changing a value that was pushed on the RLO previously modifies the RLO post hoc. This fix should allow for correct results when a value that contributes to the RLO is modified.
1 parent 1e99394 commit ecd884a

File tree

2 files changed

+44
-0
lines changed

2 files changed

+44
-0
lines changed

src/statement-list/statement_list_typecheck.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ Author: Matthias Weiss, [email protected]
3333
#define CPROVER_ASSERT "\"" CPROVER_PREFIX "assert\""
3434
/// Name of the CBMC assume function.
3535
#define CPROVER_ASSUME "\"" CPROVER_PREFIX "assume\""
36+
/// Name of the RLO symbol used in some operations.
37+
#define CPROVER_TEMP_RLO CPROVER_PREFIX "temp_rlo"
3638

3739
/// Creates the artificial data block parameter with a generic name and the
3840
/// specified type.
@@ -94,6 +96,8 @@ void statement_list_typecheckt::typecheck()
9496
parse_tree.function_blocks)
9597
typecheck_function_block_declaration(fb);
9698
typecheck_tag_list();
99+
// Temporary RLO symbol for certain operations.
100+
add_temp_rlo();
97101

98102
// Iterate through all networks to generate the function bodies.
99103
for(const statement_list_parse_treet::function_blockt &fb :
@@ -197,6 +201,19 @@ void statement_list_typecheckt::typecheck_tag_list()
197201
}
198202
}
199203

204+
void statement_list_typecheckt::add_temp_rlo()
205+
{
206+
symbolt temp_rlo;
207+
temp_rlo.is_static_lifetime = true;
208+
temp_rlo.module = module;
209+
temp_rlo.name = CPROVER_TEMP_RLO;
210+
temp_rlo.base_name = temp_rlo.name;
211+
temp_rlo.pretty_name = temp_rlo.name;
212+
temp_rlo.type = get_bool_type();
213+
temp_rlo.mode = ID_statement_list;
214+
symbol_table.add(temp_rlo);
215+
}
216+
200217
struct_typet statement_list_typecheckt::create_instance_data_block_type(
201218
const statement_list_parse_treet::function_blockt &function_block)
202219
{
@@ -1001,6 +1018,9 @@ void statement_list_typecheckt::typecheck_statement_list_assign(
10011018
tia_element.value.add_to_operands(assignment);
10021019
fc_bit = false;
10031020
or_bit = false;
1021+
// Set RLO to assigned operand in order to prevent false results if a symbol
1022+
// that's implicitly part of the RLO was changed by the assignment.
1023+
rlo_bit = lhs;
10041024
}
10051025

10061026
void statement_list_typecheckt::typecheck_statement_list_set_rlo(
@@ -1027,6 +1047,9 @@ void statement_list_typecheckt::typecheck_statement_list_set(
10271047
{
10281048
const symbol_exprt &op{typecheck_instruction_with_non_const_operand(op_code)};
10291049
const irep_idt &identifier{op.get_identifier()};
1050+
1051+
save_rlo_state(tia_element);
1052+
10301053
const exprt lhs{typecheck_identifier(tia_element, identifier)};
10311054
const code_assignt assignment{lhs, true_exprt()};
10321055
const code_ifthenelset ifthen{rlo_bit, assignment};
@@ -1041,6 +1064,9 @@ void statement_list_typecheckt::typecheck_statement_list_reset(
10411064
{
10421065
const symbol_exprt &op{typecheck_instruction_with_non_const_operand(op_code)};
10431066
const irep_idt &identifier{op.get_identifier()};
1067+
1068+
save_rlo_state(tia_element);
1069+
10441070
const exprt lhs{typecheck_identifier(tia_element, identifier)};
10451071
const code_assignt assignment{lhs, false_exprt()};
10461072
const code_ifthenelset ifthen{rlo_bit, assignment};
@@ -1480,3 +1506,12 @@ void statement_list_typecheckt::initialize_bit_expression(const exprt &op)
14801506
or_bit = false;
14811507
rlo_bit = op;
14821508
}
1509+
1510+
void statement_list_typecheckt::save_rlo_state(symbolt &tia_element)
1511+
{
1512+
symbol_exprt temp_rlo{
1513+
symbol_table.get_writeable_ref(CPROVER_TEMP_RLO).symbol_expr()};
1514+
const code_assignt rlo_assignment{temp_rlo, rlo_bit};
1515+
tia_element.value.add_to_operands(rlo_assignment);
1516+
rlo_bit = temp_rlo;
1517+
}

src/statement-list/statement_list_typecheck.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,10 @@ class statement_list_typecheckt : public typecheckt
129129
/// adds symbols for its contents to the symbol table.
130130
void typecheck_tag_list();
131131

132+
/// Adds a symbol for the RLO to the symbol table. This symbol is used by
133+
/// other operations to save intermediate results of the rlo expression.
134+
void add_temp_rlo();
135+
132136
/// Creates a data block type for the given function block.
133137
/// \param function_block: Function block with an interface that should be
134138
/// converted to a data block.
@@ -624,6 +628,11 @@ class statement_list_typecheckt : public typecheckt
624628
/// instruction was encontered.
625629
/// \param op: Operand of the encountered instruction.
626630
void initialize_bit_expression(const exprt &op);
631+
632+
/// Saves the current RLO bit to a temporary variable to prevent false
633+
/// overrides when modifying boolean variables.
634+
/// \param tia_element: Symbol representation of the TIA element.
635+
void save_rlo_state(symbolt &tia_element);
627636
};
628637

629638
#endif // CPROVER_STATEMENT_LIST_STATEMENT_LIST_TYPECHECK_H

0 commit comments

Comments
 (0)