@@ -79,8 +79,9 @@ void goto_symext::apply_goto_condition(
79
79
// / \param value_set: The value-set for looking up what the symbol can point to
80
80
// / \param language_mode: The language mode
81
81
// / \param ns: A namespace
82
- static void try_evaluate_pointer_comparisons_base_case (
83
- renamedt<exprt, L2> &condition,
82
+ static optionalt<renamedt<exprt, L2>>
83
+ try_evaluate_pointer_comparison (
84
+ irep_idt operation,
84
85
const symbol_exprt &symbol_expr,
85
86
const exprt &other_operand,
86
87
const value_sett &value_set,
@@ -116,7 +117,7 @@ static void try_evaluate_pointer_comparisons_base_case(
116
117
{
117
118
// If ID_unknown or ID_invalid are in the value-set then we can't
118
119
// conclude anything about it
119
- return ;
120
+ return {} ;
120
121
}
121
122
122
123
if (!constant_found)
@@ -142,20 +143,22 @@ static void try_evaluate_pointer_comparisons_base_case(
142
143
{
143
144
// The symbol cannot possibly have the value \p other_operand because it
144
145
// isn't in the symbol's value-set
145
- condition = condition. get (). id () == ID_equal ? make_renamed<L2>(false_exprt{})
146
- : make_renamed<L2>(true_exprt{});
146
+ return operation == ID_equal ? make_renamed<L2>(false_exprt{})
147
+ : make_renamed<L2>(true_exprt{});
147
148
}
148
149
else if (value_set_elements.size () == 1 )
149
150
{
150
151
// The symbol must have the value \p other_operand because it is the only
151
152
// thing in the symbol's value-set
152
- condition = condition.get ().id () == ID_equal ? make_renamed<L2>(true_exprt{})
153
- : make_renamed<L2>(false_exprt{});
153
+ return operation == ID_equal ? make_renamed<L2>(true_exprt{})
154
+ : make_renamed<L2>(false_exprt{});
155
+ }
156
+ else
157
+ {
158
+ return {};
154
159
}
155
160
}
156
161
157
-
158
-
159
162
// / Check if we have a simple pointer comparison, and if so try to evaluate it.
160
163
// / \param [in,out] condition: An L2- renamed expression of the form
161
164
// / "symbol_expr == other" or "symbol_expr != other" (or one of those with
@@ -168,30 +171,34 @@ static void try_evaluate_pointer_comparisons_base_case(
168
171
// / \param value_set: The value-set for looking up what the symbol can point to
169
172
// / \param language_mode: The language mode
170
173
// / \param ns: A namespace
171
- static bool try_evaluate_pointer_comparisons_base_case_with_check (
172
- renamedt<exprt, L2> &condition,
173
- const exprt &symbol_expr,
174
- const exprt &other_operand,
174
+ static optionalt<renamedt<exprt, L2>>
175
+ try_evaluate_pointer_comparison (
176
+ const exprt &expr,
175
177
const value_sett &value_set,
176
178
const irep_idt language_mode,
177
179
const namespacet &ns)
178
180
{
181
+ if (expr.id () != ID_equal && expr.id () != ID_notequal)
182
+ return {};
183
+
184
+ if (!can_cast_type<pointer_typet>(expr.op0 ().type ()))
185
+ return {};
186
+
187
+ exprt lhs = expr.op0 (), rhs = expr.op1 ();
188
+ if (can_cast_expr<symbol_exprt>(rhs))
189
+ std::swap (lhs, rhs);
190
+
179
191
const symbol_exprt *symbol_expr_lhs =
180
- expr_try_dynamic_cast<symbol_exprt>(symbol_expr );
192
+ expr_try_dynamic_cast<symbol_exprt>(lhs );
181
193
182
194
if (!symbol_expr_lhs)
183
- {
184
- return false ;
185
- }
195
+ return {};
186
196
187
- if (!goto_symex_is_constantt ()(other_operand))
188
- {
189
- return false ;
190
- }
197
+ if (!goto_symex_is_constantt ()(rhs))
198
+ return {};
191
199
192
- try_evaluate_pointer_comparisons_base_case (
193
- condition, *symbol_expr_lhs, other_operand, value_set, language_mode, ns);
194
- return true ;
200
+ return try_evaluate_pointer_comparison (
201
+ expr.id (), *symbol_expr_lhs, rhs, value_set, language_mode, ns);
195
202
}
196
203
197
204
// / Try to evaluate pointer comparisons where they can be trivially determined
@@ -208,37 +215,11 @@ static renamedt<exprt, L2> try_evaluate_pointer_comparisons(
208
215
const irep_idt language_mode,
209
216
const namespacet &ns)
210
217
{
211
- const exprt &condition_expr = condition.get ();
212
- if (condition_expr.id () == ID_equal || condition_expr.id () == ID_notequal)
213
- {
214
- if (can_cast_type<pointer_typet>(condition_expr.op0 ().type ()))
215
- {
216
- // Check if this is the form "symbol rel constant" or "constant rel symbol"
217
- if (!try_evaluate_pointer_comparisons_base_case_with_check (
218
- condition,
219
- condition_expr.op0 (),
220
- condition_expr.op1 (),
221
- value_set,
222
- language_mode,
223
- ns))
224
- {
225
- try_evaluate_pointer_comparisons_base_case_with_check (
226
- condition,
227
- condition_expr.op1 (),
228
- condition_expr.op0 (),
229
- value_set,
230
- language_mode,
231
- ns);
232
- }
233
- }
234
- }
235
- else
236
- {
237
- condition.operands ().for_each ([&](renamedt<exprt, L2> &op) {
238
- op = try_evaluate_pointer_comparisons (
239
- std::move (op), value_set, language_mode, ns);
218
+ condition.selectively_mutate (
219
+ [&value_set, &language_mode, &ns](const exprt &expr) {
220
+ return try_evaluate_pointer_comparison (
221
+ expr, value_set, language_mode, ns);
240
222
});
241
- }
242
223
243
224
return condition;
244
225
}
0 commit comments