Skip to content

Commit 49ac991

Browse files
committed
Implement union values
Reuse get_struct_member for unions (copy-paste).
1 parent aad1fa6 commit 49ac991

File tree

2 files changed

+48
-1
lines changed

2 files changed

+48
-1
lines changed

src/memory-analyzer/analyze_symbol.cpp

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,11 @@ exprt gdb_value_extractort::get_expr_value(
429429

430430
return get_pointer_value(expr, zero_expr, location);
431431
}
432-
UNIMPLEMENTED;
432+
else if(type.id() == ID_union_tag)
433+
{
434+
return get_union_value(expr, zero_expr, location);
435+
}
436+
UNREACHABLE;
433437
}
434438

435439
exprt gdb_value_extractort::get_struct_value(
@@ -465,6 +469,39 @@ exprt gdb_value_extractort::get_struct_value(
465469
return new_expr;
466470
}
467471

472+
exprt gdb_value_extractort::get_union_value(
473+
const exprt &expr,
474+
const exprt &zero_expr,
475+
const source_locationt &location)
476+
{
477+
PRECONDITION(zero_expr.id() == ID_union);
478+
479+
PRECONDITION(expr.type().id() == ID_union_tag);
480+
PRECONDITION(expr.type() == zero_expr.type());
481+
482+
exprt new_expr(zero_expr);
483+
484+
const union_tag_typet &union_tag_type = to_union_tag_type(expr.type());
485+
const union_typet union_type = ns.follow_tag(union_tag_type);
486+
487+
for(size_t i = 0; i < new_expr.operands().size(); ++i)
488+
{
489+
const union_typet::componentt &component = union_type.components()[i];
490+
491+
if(component.get_is_padding())
492+
{
493+
continue;
494+
}
495+
496+
exprt &operand = new_expr.operands()[i];
497+
member_exprt member_expr(expr, component);
498+
499+
operand = get_expr_value(member_expr, operand, location);
500+
}
501+
502+
return new_expr;
503+
}
504+
468505
void gdb_value_extractort::process_outstanding_assignments()
469506
{
470507
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)