33
33
#define CPROVER_ASSERT " \" " CPROVER_PREFIX " assert\" "
34
34
// / Name of the CBMC assume function.
35
35
#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"
36
38
37
39
// / Creates the artificial data block parameter with a generic name and the
38
40
// / specified type.
@@ -94,6 +96,8 @@ void statement_list_typecheckt::typecheck()
94
96
parse_tree.function_blocks )
95
97
typecheck_function_block_declaration (fb);
96
98
typecheck_tag_list ();
99
+ // Temporary RLO symbol for certain operations.
100
+ add_temp_rlo ();
97
101
98
102
// Iterate through all networks to generate the function bodies.
99
103
for (const statement_list_parse_treet::function_blockt &fb :
@@ -197,6 +201,19 @@ void statement_list_typecheckt::typecheck_tag_list()
197
201
}
198
202
}
199
203
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
+
200
217
struct_typet statement_list_typecheckt::create_instance_data_block_type (
201
218
const statement_list_parse_treet::function_blockt &function_block)
202
219
{
@@ -1001,6 +1018,9 @@ void statement_list_typecheckt::typecheck_statement_list_assign(
1001
1018
tia_element.value .add_to_operands (assignment);
1002
1019
fc_bit = false ;
1003
1020
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;
1004
1024
}
1005
1025
1006
1026
void statement_list_typecheckt::typecheck_statement_list_set_rlo (
@@ -1027,6 +1047,9 @@ void statement_list_typecheckt::typecheck_statement_list_set(
1027
1047
{
1028
1048
const symbol_exprt &op{typecheck_instruction_with_non_const_operand (op_code)};
1029
1049
const irep_idt &identifier{op.get_identifier ()};
1050
+
1051
+ save_rlo_state (tia_element);
1052
+
1030
1053
const exprt lhs{typecheck_identifier (tia_element, identifier)};
1031
1054
const code_assignt assignment{lhs, true_exprt ()};
1032
1055
const code_ifthenelset ifthen{rlo_bit, assignment};
@@ -1041,6 +1064,9 @@ void statement_list_typecheckt::typecheck_statement_list_reset(
1041
1064
{
1042
1065
const symbol_exprt &op{typecheck_instruction_with_non_const_operand (op_code)};
1043
1066
const irep_idt &identifier{op.get_identifier ()};
1067
+
1068
+ save_rlo_state (tia_element);
1069
+
1044
1070
const exprt lhs{typecheck_identifier (tia_element, identifier)};
1045
1071
const code_assignt assignment{lhs, false_exprt ()};
1046
1072
const code_ifthenelset ifthen{rlo_bit, assignment};
@@ -1480,3 +1506,12 @@ void statement_list_typecheckt::initialize_bit_expression(const exprt &op)
1480
1506
or_bit = false ;
1481
1507
rlo_bit = op;
1482
1508
}
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
+ }
0 commit comments