Skip to content

Commit f732825

Browse files
authored
fix #18101 wrong code generated for bitfield assignment to ?: (#21666)
1 parent 4d33ac2 commit f732825

2 files changed

Lines changed: 18 additions & 4 deletions

File tree

compiler/src/dmd/expressionsem.d

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -621,7 +621,7 @@ TupleDeclaration isAliasThisTuple(Expression e)
621621
*/
622622
Expression addressOf(Expression e)
623623
{
624-
//printf("Expression::addressOf()\n");
624+
//printf("Expression::addressOf() %s\n", e.toChars());
625625
debug
626626
{
627627
assert(e.op == EXP.error || e.isLvalue());
@@ -16213,7 +16213,9 @@ private Expression toLvalueImpl(Expression _this, Scope* sc, const(char)* action
1621316213
// convert (econd ? e1 : e2) to *(econd ? &e1 : &e2)
1621416214
CondExp e = cast(CondExp)(_this.copy());
1621516215
e.e1 = _this.e1.toLvalue(sc, action).addressOf();
16216+
checkAddressable(e.e1, sc);
1621616217
e.e2 = _this.e2.toLvalue(sc, action).addressOf();
16218+
checkAddressable(e.e2, sc);
1621716219
e.type = _this.type.pointerTo();
1621816220
return new PtrExp(_this.loc, e, _this.type);
1621916221

@@ -16600,6 +16602,7 @@ private bool checkAddressVar(Scope* sc, Expression exp, VarDeclaration v)
1660016602
*/
1660116603
bool checkAddressable(Expression e, Scope* sc)
1660216604
{
16605+
//printf("checkAddressable() %s\n", e.toChars());
1660316606
Expression ex = e;
1660416607
while (true)
1660516608
{
@@ -16627,7 +16630,7 @@ bool checkAddressable(Expression e, Scope* sc)
1662716630
continue;
1662816631

1662916632
case EXP.variable:
16630-
if (sc.inCfile)
16633+
if (sc && sc.inCfile)
1663116634
{
1663216635
// C11 6.5.3.2: A variable that has its address taken cannot be
1663316636
// stored in a register.

compiler/test/fail_compilation/biterrors5.d

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
/* REQUIRED_ARGS: -preview=bitfields
22
* TEST_OUTPUT:
33
---
4-
fail_compilation/biterrors5.d(23): Error: bitfield symbol expected not struct `biterrors5.S`
5-
fail_compilation/biterrors5.d(24): Error: bitfield symbol expected not variable `biterrors5.test0.i`
4+
fail_compilation/biterrors5.d(25): Error: bitfield symbol expected not struct `biterrors5.S`
5+
fail_compilation/biterrors5.d(26): Error: bitfield symbol expected not variable `biterrors5.test0.i`
6+
fail_compilation/biterrors5.d(35): Error: cannot take address of bit-field `x`
7+
fail_compilation/biterrors5.d(35): Error: cannot take address of bit-field `y`
68
---
79
*/
810

@@ -23,3 +25,12 @@ void test0()
2325
i = __traits(getBitfieldOffset, S);
2426
i = __traits(getBitfieldOffset, i);
2527
}
28+
29+
/****************************************/
30+
31+
struct B { int x: 3; int y: 5; }
32+
33+
void test1(int val, int choice, B a)
34+
{
35+
(choice ? a.x : a.y) = val;
36+
}

0 commit comments

Comments
 (0)