@@ -63,21 +63,17 @@ struct simplify_expr_cachet
63
63
simplify_expr_cachet simplify_expr_cache;
64
64
#endif
65
65
66
- bool simplify_exprt::simplify_abs (exprt &expr)
66
+ simplify_exprt::resultt<> simplify_exprt::simplify_abs (const abs_exprt &expr)
67
67
{
68
- if (expr.operands ().size ()!=1 )
69
- return true ;
70
-
71
- if (to_unary_expr (expr).op ().is_constant ())
68
+ if (expr.op ().is_constant ())
72
69
{
73
70
const typet &type = to_unary_expr (expr).op ().type ();
74
71
75
72
if (type.id ()==ID_floatbv)
76
73
{
77
74
ieee_floatt value (to_constant_expr (to_unary_expr (expr).op ()));
78
75
value.set_sign (false );
79
- expr=value.to_expr ();
80
- return false ;
76
+ return value.to_expr ();
81
77
}
82
78
else if (type.id ()==ID_signedbv ||
83
79
type.id ()==ID_unsignedbv)
@@ -87,20 +83,18 @@ bool simplify_exprt::simplify_abs(exprt &expr)
87
83
{
88
84
if (*value >= 0 )
89
85
{
90
- expr = to_unary_expr (expr).op ();
91
- return false ;
86
+ return to_unary_expr (expr).op ();
92
87
}
93
88
else
94
89
{
95
90
value->negate ();
96
- expr = from_integer (*value, type);
97
- return false ;
91
+ return from_integer (*value, type);
98
92
}
99
93
}
100
94
}
101
95
}
102
96
103
- return true ;
97
+ return unchanged (expr) ;
104
98
}
105
99
106
100
bool simplify_exprt::simplify_sign (exprt &expr)
@@ -133,7 +127,8 @@ bool simplify_exprt::simplify_sign(exprt &expr)
133
127
return true ;
134
128
}
135
129
136
- bool simplify_exprt::simplify_popcount (popcount_exprt &expr)
130
+ simplify_exprt::resultt<>
131
+ simplify_exprt::simplify_popcount (const popcount_exprt &expr)
137
132
{
138
133
const exprt &op = expr.op ();
139
134
@@ -151,41 +146,35 @@ bool simplify_exprt::simplify_popcount(popcount_exprt &expr)
151
146
if (get_bvrep_bit (value, width, i))
152
147
result++;
153
148
154
- auto result_expr = from_integer (result, expr.type ());
155
- expr.swap (result_expr);
156
-
157
- return false ;
149
+ return from_integer (result, expr.type ());
158
150
}
159
151
}
160
152
161
- return true ;
153
+ return unchanged (expr) ;
162
154
}
163
155
164
- bool simplify_exprt::simplify_function_application (exprt &expr)
156
+ simplify_exprt::resultt<> simplify_exprt::simplify_function_application (
157
+ const function_application_exprt &expr)
165
158
{
166
- const function_application_exprt &function_app =
167
- to_function_application_expr (expr);
168
-
169
- if (function_app.function ().id () != ID_symbol)
170
- return true ;
159
+ if (expr.function ().id () != ID_symbol)
160
+ return unchanged (expr);
171
161
172
- const irep_idt func_id =
173
- to_symbol_expr (function_app.function ()).get_identifier ();
162
+ const irep_idt &func_id = to_symbol_expr (expr.function ()).get_identifier ();
174
163
175
164
// Starts-with is used for .equals.
176
165
if (func_id == ID_cprover_string_startswith_func)
177
166
{
178
167
// We want to get both arguments of any starts-with comparison, and
179
168
// trace them back to the actual string instance. All variables on the
180
169
// way must be constant for us to be sure this will work.
181
- auto &first_argument = to_string_expr (function_app .arguments ().at (0 ));
182
- auto &second_argument = to_string_expr (function_app .arguments ().at (1 ));
170
+ auto &first_argument = to_string_expr (expr .arguments ().at (0 ));
171
+ auto &second_argument = to_string_expr (expr .arguments ().at (1 ));
183
172
184
173
const auto first_value_opt = try_get_string_data_array (first_argument, ns);
185
174
186
175
if (!first_value_opt)
187
176
{
188
- return true ;
177
+ return unchanged (expr) ;
189
178
}
190
179
191
180
const array_exprt &first_value = first_value_opt->get ();
@@ -195,17 +184,17 @@ bool simplify_exprt::simplify_function_application(exprt &expr)
195
184
196
185
if (!second_value_opt)
197
186
{
198
- return true ;
187
+ return unchanged (expr) ;
199
188
}
200
189
201
190
const array_exprt &second_value = second_value_opt->get ();
202
191
203
192
mp_integer offset_int = 0 ;
204
- if (function_app .arguments ().size () == 3 )
193
+ if (expr .arguments ().size () == 3 )
205
194
{
206
- auto &offset = function_app .arguments ()[2 ];
195
+ auto &offset = expr .arguments ()[2 ];
207
196
if (offset.id () != ID_constant)
208
- return true ;
197
+ return unchanged (expr) ;
209
198
offset_int = numeric_cast_v<mp_integer>(to_constant_expr (offset));
210
199
}
211
200
@@ -232,26 +221,25 @@ bool simplify_exprt::simplify_function_application(exprt &expr)
232
221
++second_it;
233
222
}
234
223
}
235
- expr = from_integer (is_prefix ? 1 : 0 , expr. type ());
236
- return false ;
224
+
225
+ return from_integer (is_prefix ? 1 : 0 , expr. type ()) ;
237
226
}
238
227
else if (func_id == ID_cprover_string_char_at_func)
239
228
{
240
- if (function_app .arguments ().at (1 ).id () != ID_constant)
229
+ if (expr .arguments ().at (1 ).id () != ID_constant)
241
230
{
242
- return true ;
231
+ return unchanged (expr) ;
243
232
}
244
233
245
- const auto &index = to_constant_expr (function_app .arguments ().at (1 ));
234
+ const auto &index = to_constant_expr (expr .arguments ().at (1 ));
246
235
247
- const refined_string_exprt &s =
248
- to_string_expr (function_app.arguments ().at (0 ));
236
+ const refined_string_exprt &s = to_string_expr (expr.arguments ().at (0 ));
249
237
250
238
const auto char_seq_opt = try_get_string_data_array (s, ns);
251
239
252
240
if (!char_seq_opt)
253
241
{
254
- return true ;
242
+ return unchanged (expr) ;
255
243
}
256
244
257
245
const array_exprt &char_seq = char_seq_opt->get ();
@@ -260,22 +248,20 @@ bool simplify_exprt::simplify_function_application(exprt &expr)
260
248
261
249
if (!i_opt || *i_opt >= char_seq.operands ().size ())
262
250
{
263
- return true ;
251
+ return unchanged (expr) ;
264
252
}
265
253
266
254
const auto &c = to_constant_expr (char_seq.operands ().at (*i_opt));
267
255
268
256
if (c.type () != expr.type ())
269
257
{
270
- return true ;
258
+ return unchanged (expr) ;
271
259
}
272
260
273
- expr = c;
274
-
275
- return false ;
261
+ return c;
276
262
}
277
263
278
- return true ;
264
+ return unchanged (expr) ;
279
265
}
280
266
281
267
simplify_exprt::resultt<>
@@ -862,38 +848,39 @@ simplify_exprt::simplify_typecast(const typecast_exprt &expr)
862
848
return unchanged (expr);
863
849
}
864
850
865
- bool simplify_exprt::simplify_dereference (exprt &expr)
851
+ simplify_exprt::resultt<>
852
+ simplify_exprt::simplify_dereference (const dereference_exprt &expr)
866
853
{
867
- const exprt &pointer= to_dereference_expr ( expr) .pointer ();
854
+ const exprt &pointer = expr.pointer ();
868
855
869
856
if (pointer.type ().id ()!=ID_pointer)
870
- return true ;
857
+ return unchanged (expr) ;
871
858
872
859
if (pointer.id ()==ID_if && pointer.operands ().size ()==3 )
873
860
{
874
861
const if_exprt &if_expr=to_if_expr (pointer);
875
862
876
- exprt tmp_op1=expr;
877
- tmp_op1.op0 ()=if_expr.true_case ();
878
- simplify_dereference (tmp_op1);
879
- exprt tmp_op2=expr;
880
- tmp_op2.op0 ()=if_expr.false_case ();
881
- simplify_dereference (tmp_op2);
863
+ auto tmp_op1 = expr;
864
+ tmp_op1.op () = if_expr.true_case ();
865
+ exprt tmp_op1_result = simplify_dereference (tmp_op1);
882
866
883
- expr=if_exprt (if_expr.cond (), tmp_op1, tmp_op2);
867
+ auto tmp_op2 = expr;
868
+ tmp_op2.op () = if_expr.false_case ();
869
+ exprt tmp_op2_result = simplify_dereference (tmp_op2);
884
870
885
- simplify_if ( to_if_expr (expr)) ;
871
+ if_exprt tmp{if_expr. cond (), tmp_op1_result, tmp_op2_result} ;
886
872
887
- return false ;
873
+ simplify_if (tmp);
874
+
875
+ return tmp;
888
876
}
889
877
890
878
if (pointer.id ()==ID_address_of)
891
879
{
892
880
exprt tmp=to_address_of_expr (pointer).object ();
893
881
// one address_of is gone, try again
894
882
simplify_rec (tmp);
895
- expr.swap (tmp);
896
- return false ;
883
+ return tmp;
897
884
}
898
885
// rewrite *(&a[0] + x) to a[x]
899
886
else if (pointer.id ()==ID_plus &&
@@ -912,13 +899,12 @@ bool simplify_exprt::simplify_dereference(exprt &expr)
912
899
pointer_offset_sum (old.index (), pointer.op1 ()),
913
900
old.array ().type ().subtype ());
914
901
simplify_rec (idx);
915
- expr.swap (idx);
916
- return false ;
902
+ return idx;
917
903
}
918
904
}
919
905
}
920
906
921
- return true ;
907
+ return unchanged (expr) ;
922
908
}
923
909
924
910
bool simplify_exprt::simplify_if_implies (
@@ -2505,7 +2491,14 @@ bool simplify_exprt::simplify_node(exprt &expr)
2505
2491
expr.id ()==ID_and)
2506
2492
no_change = simplify_boolean (expr) && no_change;
2507
2493
else if (expr.id ()==ID_dereference)
2508
- no_change = simplify_dereference (expr) && no_change;
2494
+ {
2495
+ auto r = simplify_dereference (to_dereference_expr (expr));
2496
+ if (r.has_changed ())
2497
+ {
2498
+ no_change = false ;
2499
+ expr = r.expr ;
2500
+ }
2501
+ }
2509
2502
else if (expr.id ()==ID_address_of)
2510
2503
no_change = simplify_address_of (expr) && no_change;
2511
2504
else if (expr.id ()==ID_pointer_offset)
@@ -2528,13 +2521,34 @@ bool simplify_exprt::simplify_node(exprt &expr)
2528
2521
else if (expr.id ()==ID_isnormal)
2529
2522
no_change = simplify_isnormal (expr) && no_change;
2530
2523
else if (expr.id ()==ID_abs)
2531
- no_change = simplify_abs (expr) && no_change;
2524
+ {
2525
+ auto r = simplify_abs (to_abs_expr (expr));
2526
+ if (r.has_changed ())
2527
+ {
2528
+ no_change = false ;
2529
+ expr = r.expr ;
2530
+ }
2531
+ }
2532
2532
else if (expr.id ()==ID_sign)
2533
2533
no_change = simplify_sign (expr) && no_change;
2534
2534
else if (expr.id () == ID_popcount)
2535
- no_change = simplify_popcount (to_popcount_expr (expr)) && no_change;
2535
+ {
2536
+ auto r = simplify_popcount (to_popcount_expr (expr));
2537
+ if (r.has_changed ())
2538
+ {
2539
+ no_change = false ;
2540
+ expr = r.expr ;
2541
+ }
2542
+ }
2536
2543
else if (expr.id () == ID_function_application)
2537
- no_change = simplify_function_application (expr) && no_change;
2544
+ {
2545
+ auto r = simplify_function_application (to_function_application_expr (expr));
2546
+ if (r.has_changed ())
2547
+ {
2548
+ no_change = false ;
2549
+ expr = r.expr ;
2550
+ }
2551
+ }
2538
2552
else if (expr.id () == ID_complex_real || expr.id () == ID_complex_imag)
2539
2553
no_change = simplify_complex (expr) && no_change;
2540
2554
0 commit comments