@@ -181,67 +181,34 @@ bool simplify_exprt::simplify_function_application(exprt &expr)
181
181
auto &first_argument = to_string_expr (function_app.arguments ().at (0 ));
182
182
auto &second_argument = to_string_expr (function_app.arguments ().at (1 ));
183
183
184
- if (
185
- first_argument. content (). id () != ID_address_of ||
186
- second_argument. content (). id () != ID_address_of )
184
+ const auto first_value_opt = try_get_string_data_array (first_argument, ns);
185
+
186
+ if (!first_value_opt )
187
187
{
188
188
return true ;
189
189
}
190
190
191
- mp_integer offset_int = 0 ;
192
- if (function_app.arguments ().size () == 3 )
193
- {
194
- auto &offset = function_app.arguments ()[2 ];
195
- if (offset.id () != ID_constant)
196
- return true ;
197
- offset_int = numeric_cast_v<mp_integer>(to_constant_expr (offset));
198
- }
191
+ const array_exprt &first_value = first_value_opt->get ();
199
192
200
- const address_of_exprt &first_address_of =
201
- to_address_of_expr (first_argument.content ());
202
- const address_of_exprt &second_address_of =
203
- to_address_of_expr (second_argument.content ());
193
+ const auto second_value_opt =
194
+ try_get_string_data_array (second_argument, ns);
204
195
205
- // Constants are got via address_of expressions, so this helps filter out
206
- // things that are non-constant.
207
- if (
208
- first_address_of.object ().id () != ID_index ||
209
- second_address_of.object ().id () != ID_index)
196
+ if (!second_value_opt)
210
197
{
211
198
return true ;
212
199
}
213
200
214
- const index_exprt &first_index_expression =
215
- to_index_expr (first_address_of.object ());
216
- const index_exprt &second_index_expression =
217
- to_index_expr (second_address_of.object ());
218
-
219
- const exprt &first_string_array = first_index_expression.array ();
220
- const exprt &second_string_array = second_index_expression.array ();
201
+ const array_exprt &second_value = second_value_opt->get ();
221
202
222
- // Check if our symbols type is an array.
223
- if (
224
- first_string_array.type ().id () != ID_array ||
225
- second_string_array.type ().id () != ID_array)
203
+ mp_integer offset_int = 0 ;
204
+ if (function_app.arguments ().size () == 3 )
226
205
{
227
- return true ;
206
+ auto &offset = function_app.arguments ()[2 ];
207
+ if (offset.id () != ID_constant)
208
+ return true ;
209
+ offset_int = numeric_cast_v<mp_integer>(to_constant_expr (offset));
228
210
}
229
211
230
- // get their initial values from the symbol table
231
- const symbolt *symbol_ptr = nullptr ;
232
- if (ns.lookup (
233
- to_symbol_expr (first_string_array).get_identifier (), symbol_ptr))
234
- return true ;
235
- const exprt &first_value = symbol_ptr->value ;
236
- if (ns.lookup (
237
- to_symbol_expr (second_string_array).get_identifier (), symbol_ptr))
238
- return true ;
239
- const exprt &second_value = symbol_ptr->value ;
240
-
241
- // only compare if both are arrays
242
- if (first_value.id () != ID_array || second_value.id () != ID_array)
243
- return true ;
244
-
245
212
// test whether second_value is a prefix of first_value
246
213
bool is_prefix =
247
214
offset_int >= 0 && mp_integer (first_value.operands ().size ()) >=
@@ -1826,6 +1793,46 @@ optionalt<std::string> simplify_exprt::expr2bits(
1826
1793
return {};
1827
1794
}
1828
1795
1796
+ optionalt<std::reference_wrapper<const array_exprt>>
1797
+ simplify_exprt::try_get_string_data_array (
1798
+ const refined_string_exprt &s,
1799
+ const namespacet &ns)
1800
+ {
1801
+ if (s.content ().id () != ID_address_of)
1802
+ {
1803
+ return {};
1804
+ }
1805
+
1806
+ const auto &content = to_address_of_expr (s.content ());
1807
+
1808
+ if (content.object ().id () != ID_index)
1809
+ {
1810
+ return {};
1811
+ }
1812
+
1813
+ const auto &array_start = to_index_expr (content.object ());
1814
+
1815
+ if (array_start.array ().id () != ID_symbol ||
1816
+ array_start.array ().type ().id () != ID_array)
1817
+ {
1818
+ return {};
1819
+ }
1820
+
1821
+ const auto &array = to_symbol_expr (array_start.array ());
1822
+
1823
+ const symbolt *symbol_ptr = nullptr ;
1824
+
1825
+ if (ns.lookup (array.get_identifier (), symbol_ptr) ||
1826
+ symbol_ptr->value .id () != ID_array)
1827
+ {
1828
+ return {};
1829
+ }
1830
+
1831
+ const auto &char_seq = to_array_expr (symbol_ptr->value );
1832
+
1833
+ return optionalt<std::reference_wrapper<const array_exprt>>(char_seq);
1834
+ }
1835
+
1829
1836
bool simplify_exprt::simplify_byte_extract (byte_extract_exprt &expr)
1830
1837
{
1831
1838
// lift up any ID_if on the object
0 commit comments