Skip to content

Commit 06d727c

Browse files
author
Daniel Kroening
committed
simplify_function_application now has new interface
This improves memory safety.
1 parent bcd7089 commit 06d727c

File tree

2 files changed

+33
-31
lines changed

2 files changed

+33
-31
lines changed

src/util/simplify_expr.cpp

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -153,31 +153,28 @@ simplify_exprt::simplify_popcount(const popcount_exprt &expr)
153153
return unchanged(expr);
154154
}
155155

156-
bool simplify_exprt::simplify_function_application(exprt &expr)
156+
simplify_exprt::resultt<> simplify_exprt::simplify_function_application(
157+
const function_application_exprt &expr)
157158
{
158-
const function_application_exprt &function_app =
159-
to_function_application_expr(expr);
159+
if(expr.function().id() != ID_symbol)
160+
return unchanged(expr);
160161

161-
if(function_app.function().id() != ID_symbol)
162-
return true;
163-
164-
const irep_idt func_id =
165-
to_symbol_expr(function_app.function()).get_identifier();
162+
const irep_idt &func_id = to_symbol_expr(expr.function()).get_identifier();
166163

167164
// Starts-with is used for .equals.
168165
if(func_id == ID_cprover_string_startswith_func)
169166
{
170167
// We want to get both arguments of any starts-with comparison, and
171168
// trace them back to the actual string instance. All variables on the
172169
// way must be constant for us to be sure this will work.
173-
auto &first_argument = to_string_expr(function_app.arguments().at(0));
174-
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));
175172

176173
const auto first_value_opt = try_get_string_data_array(first_argument, ns);
177174

178175
if(!first_value_opt)
179176
{
180-
return true;
177+
return unchanged(expr);
181178
}
182179

183180
const array_exprt &first_value = first_value_opt->get();
@@ -187,17 +184,17 @@ bool simplify_exprt::simplify_function_application(exprt &expr)
187184

188185
if(!second_value_opt)
189186
{
190-
return true;
187+
return unchanged(expr);
191188
}
192189

193190
const array_exprt &second_value = second_value_opt->get();
194191

195192
mp_integer offset_int = 0;
196-
if(function_app.arguments().size() == 3)
193+
if(expr.arguments().size() == 3)
197194
{
198-
auto &offset = function_app.arguments()[2];
195+
auto &offset = expr.arguments()[2];
199196
if(offset.id() != ID_constant)
200-
return true;
197+
return unchanged(expr);
201198
offset_int = numeric_cast_v<mp_integer>(to_constant_expr(offset));
202199
}
203200

@@ -224,26 +221,25 @@ bool simplify_exprt::simplify_function_application(exprt &expr)
224221
++second_it;
225222
}
226223
}
227-
expr = from_integer(is_prefix ? 1 : 0, expr.type());
228-
return false;
224+
225+
return from_integer(is_prefix ? 1 : 0, expr.type());
229226
}
230227
else if(func_id == ID_cprover_string_char_at_func)
231228
{
232-
if(function_app.arguments().at(1).id() != ID_constant)
229+
if(expr.arguments().at(1).id() != ID_constant)
233230
{
234-
return true;
231+
return unchanged(expr);
235232
}
236233

237-
const auto &index = to_constant_expr(function_app.arguments().at(1));
234+
const auto &index = to_constant_expr(expr.arguments().at(1));
238235

239-
const refined_string_exprt &s =
240-
to_string_expr(function_app.arguments().at(0));
236+
const refined_string_exprt &s = to_string_expr(expr.arguments().at(0));
241237

242238
const auto char_seq_opt = try_get_string_data_array(s, ns);
243239

244240
if(!char_seq_opt)
245241
{
246-
return true;
242+
return unchanged(expr);
247243
}
248244

249245
const array_exprt &char_seq = char_seq_opt->get();
@@ -252,22 +248,20 @@ bool simplify_exprt::simplify_function_application(exprt &expr)
252248

253249
if(!i_opt || *i_opt >= char_seq.operands().size())
254250
{
255-
return true;
251+
return unchanged(expr);
256252
}
257253

258254
const auto &c = to_constant_expr(char_seq.operands().at(*i_opt));
259255

260256
if(c.type() != expr.type())
261257
{
262-
return true;
258+
return unchanged(expr);
263259
}
264260

265-
expr = c;
266-
267-
return false;
261+
return c;
268262
}
269263

270-
return true;
264+
return unchanged(expr);
271265
}
272266

273267
simplify_exprt::resultt<>
@@ -2540,7 +2534,14 @@ bool simplify_exprt::simplify_node(exprt &expr)
25402534
}
25412535
}
25422536
else if(expr.id() == ID_function_application)
2543-
no_change = simplify_function_application(expr) && no_change;
2537+
{
2538+
auto r = simplify_function_application(to_function_application_expr(expr));
2539+
if(r.has_changed())
2540+
{
2541+
no_change = false;
2542+
expr = r.expr;
2543+
}
2544+
}
25442545
else if(expr.id() == ID_complex_real || expr.id() == ID_complex_imag)
25452546
no_change = simplify_complex(expr) && no_change;
25462547

src/util/simplify_expr_class.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ class byte_extract_exprt;
3232
class byte_update_exprt;
3333
class exprt;
3434
class extractbits_exprt;
35+
class function_application_exprt;
3536
class if_exprt;
3637
class index_exprt;
3738
class member_exprt;
@@ -167,7 +168,7 @@ class simplify_exprt
167168

168169
/// Attempt to simplify mathematical function applications if we have
169170
/// enough information to do so. Currently focused on constant comparisons.
170-
bool simplify_function_application(exprt &expr);
171+
resultt<> simplify_function_application(const function_application_exprt &);
171172

172173
// auxiliary
173174
bool simplify_if_implies(

0 commit comments

Comments
 (0)