1313#include < util/c_types_util.h>
1414#include < util/config.h>
1515#include < util/expr_initializer.h>
16+ #include < util/pointer_offset_size.h>
17+ #include < util/string2int.h>
1618#include < util/string_constant.h>
19+ #include < util/string_utils.h>
1720
1821gdb_value_extractort::gdb_value_extractort (
1922 const symbol_tablet &symbol_table,
@@ -167,6 +170,43 @@ exprt gdb_value_extractort::get_char_pointer_value(
167170 }
168171}
169172
173+ exprt gdb_value_extractort::get_pointer_to_member_value (
174+ const exprt &expr,
175+ const pointer_valuet &pointer_value,
176+ const source_locationt &location)
177+ {
178+ PRECONDITION (expr.type ().id () == ID_pointer);
179+ PRECONDITION (!is_c_char_type (expr.type ().subtype ()));
180+ std::string memory_location = pointer_value.address .string ();
181+ PRECONDITION (memory_location != " 0x0" );
182+ PRECONDITION (!pointer_value.pointee .empty ());
183+
184+ std::string struct_name;
185+ size_t member_offset;
186+ if (pointer_value.pointee .find (" +" ) != std::string::npos)
187+ {
188+ std::string member_offset_string;
189+ split_string (
190+ pointer_value.pointee , ' +' , struct_name, member_offset_string, true );
191+ member_offset = safe_string2size_t (member_offset_string);
192+ }
193+ else
194+ {
195+ struct_name = pointer_value.pointee ;
196+ member_offset = 0 ;
197+ }
198+
199+ const symbolt *struct_symbol = symbol_table.lookup (struct_name);
200+ DATA_INVARIANT (struct_symbol != nullptr , " unknown struct" );
201+
202+ const auto maybe_member_expr = get_subexpression_at_offset (
203+ struct_symbol->symbol_expr (), member_offset, expr.type ().subtype (), ns);
204+ if (maybe_member_expr.has_value ())
205+ return *maybe_member_expr;
206+
207+ UNREACHABLE;
208+ }
209+
170210exprt gdb_value_extractort::get_non_char_pointer_value (
171211 const exprt &expr,
172212 const memory_addresst &memory_location,
@@ -212,6 +252,24 @@ exprt gdb_value_extractort::get_non_char_pointer_value(
212252 }
213253}
214254
255+ bool gdb_value_extractort::points_to_member (
256+ const pointer_valuet &pointer_value) const
257+ {
258+ if (pointer_value.pointee .find (" +" ) != std::string::npos)
259+ return true ;
260+
261+ const symbolt *pointee_symbol = symbol_table.lookup (pointer_value.pointee );
262+ if (pointee_symbol == nullptr )
263+ return false ;
264+ const auto pointee_type = pointee_symbol->type ;
265+ if (
266+ pointee_type.id () == ID_struct_tag || pointee_type.id () == ID_union_tag ||
267+ pointee_type.id () == ID_array || pointee_type.id () == ID_struct ||
268+ pointee_type.id () == ID_union)
269+ return true ;
270+ return false ;
271+ }
272+
215273exprt gdb_value_extractort::get_pointer_value (
216274 const exprt &expr,
217275 const exprt &zero_expr,
@@ -236,7 +294,9 @@ exprt gdb_value_extractort::get_pointer_value(
236294 else
237295 {
238296 const exprt target_expr =
239- get_non_char_pointer_value (expr, memory_location, location);
297+ points_to_member (value)
298+ ? get_pointer_to_member_value (expr, value, location)
299+ : get_non_char_pointer_value (expr, memory_location, location);
240300
241301 if (target_expr.id () == ID_nil)
242302 {
0 commit comments