35
35
#include < util/expr_initializer.h>
36
36
#include < util/irep.h>
37
37
#include < util/mp_arith.h>
38
+ #include < util/pointer_offset_size.h>
38
39
#include < util/std_code.h>
39
40
#include < util/std_expr.h>
40
41
#include < util/std_types.h>
41
42
#include < util/string_constant.h>
43
+ #include < util/string_utils.h>
44
+ #include < util/string2int.h>
42
45
43
46
symbol_analyzert::symbol_analyzert (
44
47
const symbol_tablet &symbol_table,
@@ -191,6 +194,43 @@ exprt symbol_analyzert::get_char_pointer_value(
191
194
}
192
195
}
193
196
197
+ exprt symbol_analyzert::get_pointer_to_member_value (
198
+ const exprt &expr,
199
+ const pointer_valuet &pointer_value,
200
+ const source_locationt &location)
201
+ {
202
+ PRECONDITION (expr.type ().id () == ID_pointer);
203
+ PRECONDITION (!is_c_char (expr.type ().subtype ()));
204
+ std::string memory_location = pointer_value.address ;
205
+ PRECONDITION (memory_location != " 0x0" );
206
+ PRECONDITION (!pointer_value.pointee .empty ());
207
+
208
+ std::string struct_name;
209
+ size_t member_offset;
210
+ if (pointer_value.pointee .find (" +" ) != std::string::npos)
211
+ {
212
+ std::string member_offset_string;
213
+ split_string (
214
+ pointer_value.pointee , ' +' , struct_name, member_offset_string, true );
215
+ member_offset = safe_string2size_t (member_offset_string);
216
+ }
217
+ else
218
+ {
219
+ struct_name = pointer_value.pointee ;
220
+ member_offset = 0 ;
221
+ }
222
+
223
+ const symbolt *struct_symbol = symbol_table.lookup (struct_name);
224
+ DATA_INVARIANT (struct_symbol != nullptr , " unknown struct" );
225
+
226
+ const auto maybe_member_expr = get_subexpression_at_offset (
227
+ struct_symbol->symbol_expr (), member_offset, expr.type ().subtype (), ns);
228
+ if (maybe_member_expr.has_value ())
229
+ return *maybe_member_expr;
230
+
231
+ UNREACHABLE;
232
+ }
233
+
194
234
exprt symbol_analyzert::get_non_char_pointer_value (
195
235
const exprt &expr,
196
236
const std::string memory_location,
@@ -236,6 +276,24 @@ exprt symbol_analyzert::get_non_char_pointer_value(
236
276
}
237
277
}
238
278
279
+ bool symbol_analyzert::points_to_member (
280
+ const pointer_valuet &pointer_value) const
281
+ {
282
+ if (pointer_value.pointee .find (" +" ) != std::string::npos)
283
+ return true ;
284
+
285
+ const symbolt *pointee_symbol = symbol_table.lookup (pointer_value.pointee );
286
+ if (pointee_symbol == nullptr )
287
+ return false ;
288
+ const auto pointee_type = pointee_symbol->type ;
289
+ if (
290
+ pointee_type.id () == ID_struct_tag || pointee_type.id () == ID_union_tag ||
291
+ pointee_type.id () == ID_array || pointee_type.id () == ID_struct ||
292
+ pointee_type.id () == ID_union)
293
+ return true ;
294
+ return false ;
295
+ }
296
+
239
297
exprt symbol_analyzert::get_pointer_value (
240
298
const exprt &expr,
241
299
const exprt &zero_expr,
@@ -260,7 +318,9 @@ exprt symbol_analyzert::get_pointer_value(
260
318
else
261
319
{
262
320
const exprt target_expr =
263
- get_non_char_pointer_value (expr, memory_location, location);
321
+ points_to_member (value)
322
+ ? get_pointer_to_member_value (expr, value, location)
323
+ : get_non_char_pointer_value (expr, memory_location, location);
264
324
265
325
if (target_expr.id () == ID_nil)
266
326
{
0 commit comments