Skip to content

Commit e040e61

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 09947ba commit e040e61

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 = STATEMENT_LIST_MODE;
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
@@ -131,6 +131,10 @@ class statement_list_typecheckt : public typecheckt
131131
/// adds symbols for its contents to the symbol table.
132132
void typecheck_tag_list();
133133

134+
/// Adds a symbol for the RLO to the symbol table. This symbol is used by
135+
/// other operations to save intermediate results of the rlo expression.
136+
void add_temp_rlo();
137+
134138
/// Creates a data block type for the given function block.
135139
/// \param function_block: Function block with an interface that should be
136140
/// converted to a data block.
@@ -626,6 +630,11 @@ class statement_list_typecheckt : public typecheckt
626630
/// instruction was encontered.
627631
/// \param op: Operand of the encountered instruction.
628632
void initialize_bit_expression(const exprt &op);
633+
634+
/// Saves the current RLO bit to a temporary variable to prevent false
635+
/// overrides when modifying boolean variables.
636+
/// \param tia_element: Symbol representation of the TIA element.
637+
void save_rlo_state(symbolt &tia_element);
629638
};
630639

631640
#endif // CPROVER_STATEMENT_LIST_STATEMENT_LIST_TYPECHECK_H

0 commit comments

Comments
 (0)