Skip to content

Commit 348028f

Browse files
Petr BauchPetr Bauch
Petr Bauch
authored and
Petr Bauch
committed
Implement union values
Reuse get_struct_member for unions (copy-paste).
1 parent eb4de71 commit 348028f

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
@@ -418,6 +418,10 @@ exprt symbol_analyzert::get_expr_value(
418418

419419
return get_pointer_value(expr, zero_expr, location);
420420
}
421+
else if(type.id() == ID_union_tag)
422+
{
423+
return get_union_value(expr, zero_expr, location);
424+
}
421425
else
422426
{
423427
throw analysis_exceptiont("unexpected expression:\n" + expr.pretty());
@@ -459,6 +463,39 @@ exprt symbol_analyzert::get_struct_value(
459463
return new_expr;
460464
}
461465

466+
exprt symbol_analyzert::get_union_value(
467+
const exprt &expr,
468+
const exprt &zero_expr,
469+
const source_locationt &location)
470+
{
471+
PRECONDITION(zero_expr.id() == ID_union);
472+
473+
PRECONDITION(expr.type().id() == ID_union_tag);
474+
PRECONDITION(expr.type() == zero_expr.type());
475+
476+
exprt new_expr(zero_expr);
477+
478+
const union_tag_typet &union_tag_type = to_union_tag_type(expr.type());
479+
const union_typet union_type = ns.follow_tag(union_tag_type);
480+
481+
for(size_t i = 0; i < new_expr.operands().size(); ++i)
482+
{
483+
const union_typet::componentt &component = union_type.components()[i];
484+
485+
if(component.get_is_padding())
486+
{
487+
continue;
488+
}
489+
490+
exprt &operand = new_expr.operands()[i];
491+
member_exprt member_expr(expr, component);
492+
493+
operand = get_expr_value(member_expr, operand, location);
494+
}
495+
496+
return new_expr;
497+
}
498+
462499
void symbol_analyzert::process_outstanding_assignments()
463500
{
464501
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
@@ -133,6 +133,16 @@ class symbol_analyzert
133133
const exprt &zero_expr,
134134
const source_locationt &location);
135135

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

0 commit comments

Comments
 (0)