Skip to content

Commit

Permalink
Fix access to anonymous bitfield element through a constant value.
Browse files Browse the repository at this point in the history
Closes #1533.
  • Loading branch information
rsmmr committed Sep 22, 2023
1 parent 56f84b8 commit 904444c
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 0 deletions.
23 changes: 23 additions & 0 deletions spicy/toolchain/src/compiler/visitors/normalizer.cc
Original file line number Diff line number Diff line change
Expand Up @@ -252,6 +252,29 @@ struct Visitor : public hilti::visitor::PostOrder<void, Visitor> {
return {};
}

void operator()(const operator_::unit::MemberConst& o, position_t p) {
auto unit = o.op0().type().tryAs<type::Unit>();
auto id = o.op1().tryAs<hilti::expression::Member>()->id();

if ( unit && id && ! unit->itemByName(id) ) {
// See if we got an anonymous bitfield with a member of that
// name. If so, rewrite the access to transparently refer to the
// member through the field's internal name.
if ( auto field_id = findBitsFieldID(unit->items(), id) ) {
auto access_field =
operator_::unit::MemberConst::Operator().instantiate({o.op0(),
hilti::expression::Member(*field_id)},
o.meta());
auto access_bits =
bitfield::Member::Operator().instantiate({std::move(access_field), o.op1()}, o.meta());

logChange(p.node, access_bits);
p.node = access_bits;
modified = true;
}
}
}

void operator()(const operator_::unit::MemberNonConst& o, position_t p) {
auto unit = o.op0().type().tryAs<type::Unit>();
auto id = o.op1().tryAs<hilti::expression::Member>()->id();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63.
255
19 changes: 19 additions & 0 deletions tests/spicy/types/bitfield/anonymous-field-const.spicy
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# @TEST-EXEC: printf '\377' | spicy-driver %INPUT >output
# @TEST-EXEC: btest-diff output

module foo;

type X = unit {
: bitfield(8) {
a: 0..7;
};
};

type Y = unit(x: X) {
on %init { print x.a; }
};

public type Z = unit {
x: X;
y: Y(self.x);
};

0 comments on commit 904444c

Please sign in to comment.