Skip to content

Commit fc968f8

Browse files
committed
Implement union values
Reuse get_struct_member for unions (copy-paste).
1 parent 8116784 commit fc968f8

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

src/memory-analyzer/analyze_symbol.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,10 @@ exprt gdb_value_extractort::get_expr_value(
384384

385385
return get_pointer_value(expr, zero_expr, location);
386386
}
387+
else if(type.id() == ID_union_tag)
388+
{
389+
return get_union_value(expr, zero_expr, location);
390+
}
387391
UNREACHABLE;
388392
}
389393

@@ -420,6 +424,39 @@ exprt gdb_value_extractort::get_struct_value(
420424
return new_expr;
421425
}
422426

427+
exprt gdb_value_extractort::get_union_value(
428+
const exprt &expr,
429+
const exprt &zero_expr,
430+
const source_locationt &location)
431+
{
432+
PRECONDITION(zero_expr.id() == ID_union);
433+
434+
PRECONDITION(expr.type().id() == ID_union_tag);
435+
PRECONDITION(expr.type() == zero_expr.type());
436+
437+
exprt new_expr(zero_expr);
438+
439+
const union_tag_typet &union_tag_type = to_union_tag_type(expr.type());
440+
const union_typet union_type = ns.follow_tag(union_tag_type);
441+
442+
for(size_t i = 0; i < new_expr.operands().size(); ++i)
443+
{
444+
const union_typet::componentt &component = union_type.components()[i];
445+
446+
if(component.get_is_padding())
447+
{
448+
continue;
449+
}
450+
451+
exprt &operand = new_expr.operands()[i];
452+
member_exprt member_expr(expr, component);
453+
454+
operand = get_expr_value(member_expr, operand, location);
455+
}
456+
457+
return new_expr;
458+
}
459+
423460
void gdb_value_extractort::process_outstanding_assignments()
424461
{
425462
for(const auto &pair : outstanding_assignments)

src/memory-analyzer/analyze_symbol.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,16 @@ class gdb_value_extractort
138138
const exprt &zero_expr,
139139
const source_locationt &location);
140140

141+
/// For each of the members of the struct: call \ref get_expr_value
142+
/// \param expr: struct expression to be analysed
143+
/// \param zero_expr: struct with zero-initialised members
144+
/// \param location: the source location
145+
/// \return the value of the struct from \ref gdb_apit
146+
exprt get_union_value(
147+
const exprt &expr,
148+
const exprt &zero_expr,
149+
const source_locationt &location);
150+
141151
/// Call \ref gdb_apit::get_memory on \p expr then split based on the
142152
/// points-to type being `char` type or not. These have dedicated functions.
143153
/// \param expr: the input pointer expression

0 commit comments

Comments
 (0)