@@ -157,11 +157,13 @@ class goto_check_ct
157157 // / guard.
158158 // / \param expr: the expression to be checked
159159 // / \param guard: the condition for when the check should be made
160- void check_rec (const exprt &expr, const guardt &guard);
160+ // / \param is_assigned: the expression is assigned to
161+ void check_rec (const exprt &expr, const guardt &guard, bool is_assigned);
161162
162163 // / Initiate the recursively analysis of \p expr with its `guard' set to TRUE.
163164 // / \param expr: the expression to be checked
164- void check (const exprt &expr);
165+ // / \param is_assigned: the expression is assigned to
166+ void check (const exprt &expr, bool is_assigned);
165167
166168 struct conditiont
167169 {
@@ -183,7 +185,7 @@ class goto_check_ct
183185 void float_div_by_zero_check (const div_exprt &, const guardt &);
184186 void mod_by_zero_check (const mod_exprt &, const guardt &);
185187 void mod_overflow_check (const mod_exprt &, const guardt &);
186- void enum_range_check (const exprt &, const guardt &);
188+ void enum_range_check (const exprt &, const guardt &, bool is_assigned );
187189 void undefined_shift_check (const shift_exprt &, const guardt &);
188190 void pointer_rel_check (const binary_exprt &, const guardt &);
189191 void pointer_overflow_check (const exprt &, const guardt &);
@@ -537,11 +539,17 @@ void goto_check_ct::float_div_by_zero_check(
537539 guard);
538540}
539541
540- void goto_check_ct::enum_range_check (const exprt &expr, const guardt &guard)
542+ void goto_check_ct::enum_range_check (
543+ const exprt &expr,
544+ const guardt &guard,
545+ bool is_assigned)
541546{
542547 if (!enable_enum_range_check)
543548 return ;
544549
550+ if (is_assigned)
551+ return ; // not in range yet
552+
545553 // we might be looking at a lowered enum_is_in_range_exprt, skip over these
546554 const auto &pragmas = expr.source_location ().get_pragmas ();
547555 for (const auto &d : pragmas)
@@ -1807,13 +1815,13 @@ void goto_check_ct::check_rec_address(const exprt &expr, const guardt &guard)
18071815
18081816 if (expr.id () == ID_dereference)
18091817 {
1810- check_rec (to_dereference_expr (expr).pointer (), guard);
1818+ check_rec (to_dereference_expr (expr).pointer (), guard, false );
18111819 }
18121820 else if (expr.id () == ID_index)
18131821 {
18141822 const index_exprt &index_expr = to_index_expr (expr);
18151823 check_rec_address (index_expr.array (), guard);
1816- check_rec (index_expr.index (), guard);
1824+ check_rec (index_expr.index (), guard, false );
18171825 }
18181826 else
18191827 {
@@ -1843,7 +1851,7 @@ void goto_check_ct::check_rec_logical_op(const exprt &expr, const guardt &guard)
18431851 return guard (implication (conjunction (constraints), expr));
18441852 };
18451853
1846- check_rec (op, new_guard);
1854+ check_rec (op, new_guard, false );
18471855
18481856 constraints.push_back (expr.id () == ID_or ? boolean_negate (op) : op);
18491857 }
@@ -1855,20 +1863,20 @@ void goto_check_ct::check_rec_if(const if_exprt &if_expr, const guardt &guard)
18551863 if_expr.cond ().is_boolean (),
18561864 " first argument of if must be boolean, but got " + if_expr.cond ().pretty ());
18571865
1858- check_rec (if_expr.cond (), guard);
1866+ check_rec (if_expr.cond (), guard, false );
18591867
18601868 {
18611869 auto new_guard = [&guard, &if_expr](exprt expr) {
18621870 return guard (implication (if_expr.cond (), std::move (expr)));
18631871 };
1864- check_rec (if_expr.true_case (), new_guard);
1872+ check_rec (if_expr.true_case (), new_guard, false );
18651873 }
18661874
18671875 {
18681876 auto new_guard = [&guard, &if_expr](exprt expr) {
18691877 return guard (implication (not_exprt (if_expr.cond ()), std::move (expr)));
18701878 };
1871- check_rec (if_expr.false_case (), new_guard);
1879+ check_rec (if_expr.false_case (), new_guard, false );
18721880 }
18731881}
18741882
@@ -1878,7 +1886,7 @@ bool goto_check_ct::check_rec_member(
18781886{
18791887 const dereference_exprt &deref = to_dereference_expr (member.struct_op ());
18801888
1881- check_rec (deref.pointer (), guard);
1889+ check_rec (deref.pointer (), guard, false );
18821890
18831891 // avoid building the following expressions when pointer_validity_check
18841892 // would return immediately anyway
@@ -1969,7 +1977,10 @@ void goto_check_ct::check_rec_arithmetic_op(
19691977 }
19701978}
19711979
1972- void goto_check_ct::check_rec (const exprt &expr, const guardt &guard)
1980+ void goto_check_ct::check_rec (
1981+ const exprt &expr,
1982+ const guardt &guard,
1983+ bool is_assigned)
19731984{
19741985 if (expr.id () == ID_exists || expr.id () == ID_forall)
19751986 {
@@ -1980,7 +1991,7 @@ void goto_check_ct::check_rec(const exprt &expr, const guardt &guard)
19801991 return guard (forall_exprt (quantifier_expr.symbol (), expr));
19811992 };
19821993
1983- check_rec (quantifier_expr.where (), new_guard);
1994+ check_rec (quantifier_expr.where (), new_guard, false );
19841995 return ;
19851996 }
19861997 else if (expr.id () == ID_address_of)
@@ -2007,10 +2018,10 @@ void goto_check_ct::check_rec(const exprt &expr, const guardt &guard)
20072018 }
20082019
20092020 for (const auto &op : expr.operands ())
2010- check_rec (op, guard);
2021+ check_rec (op, guard, false );
20112022
20122023 if (expr.type ().id () == ID_c_enum_tag)
2013- enum_range_check (expr, guard);
2024+ enum_range_check (expr, guard, is_assigned );
20142025
20152026 if (expr.id () == ID_index)
20162027 {
@@ -2059,9 +2070,9 @@ void goto_check_ct::check_rec(const exprt &expr, const guardt &guard)
20592070 }
20602071}
20612072
2062- void goto_check_ct::check (const exprt &expr)
2073+ void goto_check_ct::check (const exprt &expr, bool is_assigned )
20632074{
2064- check_rec (expr, identity);
2075+ check_rec (expr, identity, is_assigned );
20652076}
20662077
20672078void goto_check_ct::memory_leak_check (const irep_idt &function_id)
@@ -2151,7 +2162,7 @@ void goto_check_ct::goto_check(
21512162
21522163 if (i.has_condition ())
21532164 {
2154- check (i.condition ());
2165+ check (i.condition (), false );
21552166 }
21562167
21572168 // magic ERROR label?
@@ -2184,45 +2195,32 @@ void goto_check_ct::goto_check(
21842195
21852196 if (statement == ID_expression)
21862197 {
2187- check (code);
2198+ check (code, false );
21882199 }
21892200 else if (statement == ID_printf)
21902201 {
21912202 for (const auto &op : code.operands ())
2192- check (op);
2203+ check (op, false );
21932204 }
21942205 }
21952206 else if (i.is_assign ())
21962207 {
21972208 const exprt &assign_lhs = i.assign_lhs ();
21982209 const exprt &assign_rhs = i.assign_rhs ();
21992210
2200- // Disable enum range checks for left-hand sides as their values are yet
2201- // to be set (by this assignment).
2202- {
2203- flag_overridet resetter (i.source_location ());
2204- resetter.disable_flag (enable_enum_range_check, " enum_range_check" );
2205- check (assign_lhs);
2206- }
2207-
2208- check (assign_rhs);
2211+ check (assign_lhs, true );
2212+ check (assign_rhs, false );
22092213
22102214 // the LHS might invalidate any assertion
22112215 invalidate (assign_lhs);
22122216 }
22132217 else if (i.is_function_call ())
22142218 {
2215- // Disable enum range checks for left-hand sides as their values are yet
2216- // to be set (by this function call).
2217- {
2218- flag_overridet resetter (i.source_location ());
2219- resetter.disable_flag (enable_enum_range_check, " enum_range_check" );
2220- check (i.call_lhs ());
2221- }
2222- check (i.call_function ());
2219+ check (i.call_lhs (), true );
2220+ check (i.call_function (), false );
22232221
22242222 for (const auto &arg : i.call_arguments ())
2225- check (arg);
2223+ check (arg, false );
22262224
22272225 check_shadow_memory_api_calls (i);
22282226
@@ -2231,7 +2229,7 @@ void goto_check_ct::goto_check(
22312229 }
22322230 else if (i.is_set_return_value ())
22332231 {
2234- check (i.return_value ());
2232+ check (i.return_value (), false );
22352233 // the return value invalidate any assertion
22362234 invalidate (i.return_value ());
22372235 }
@@ -2342,7 +2340,7 @@ void goto_check_ct::check_shadow_memory_api_calls(
23422340 {
23432341 const exprt &expr = i.call_arguments ()[0 ];
23442342 PRECONDITION (expr.type ().id () == ID_pointer);
2345- check (dereference_exprt (expr));
2343+ check (dereference_exprt (expr), false );
23462344 }
23472345}
23482346
0 commit comments