Two related statement-expression value bugs in c2mir (both gcc-divergent; reproduced on stock c2m):
1. A struct/union statement-expression value reuses a stack slot
({ ...; obj; }) whose value is a struct/union returns the lvalue of an in-block local, but c2mir reuses that local's stack slot across non-overlapping sibling scopes. With two such statement-expressions in one expression, both reads see whichever block ran last:
struct large { int x, y[9]; };
int main (void) {
int d = ({ struct large t; t.x = 2; t; }).x
- ({ struct large t; t.x = 1; t; }).x;
return d == 1 ? 0 : 1; /* gcc: 1; got: 0 */
}
(gcc.c-torture/execute/20020320-1.c aborts on master.)
2. A statement-expression ending in x++/x-- leaves an undef operand
c2mir gens expression-statements value-discarded, but post-inc/dec only materialize their old value in value context, so a statement-expression ending in x-- used as a value/condition yields an undef operand:
void g (int i) {}
void f (int i) { while ( ({ i--; }) ) g (0); }
int main (void) { f (10); return 0; }
(gcc.c-torture/execute/950906-1.c fails on master.)
Both pass with the fix.
🤖 Found during a source review with Claude Code
Fix in #453.
Two related statement-expression value bugs in c2mir (both gcc-divergent; reproduced on stock
c2m):1. A struct/union statement-expression value reuses a stack slot
({ ...; obj; })whose value is a struct/union returns the lvalue of an in-block local, but c2mir reuses that local's stack slot across non-overlapping sibling scopes. With two such statement-expressions in one expression, both reads see whichever block ran last:(
gcc.c-torture/execute/20020320-1.caborts onmaster.)2. A statement-expression ending in
x++/x--leaves an undef operandc2mir gens expression-statements value-discarded, but post-inc/dec only materialize their old value in value context, so a statement-expression ending in
x--used as a value/condition yields an undef operand:(
gcc.c-torture/execute/950906-1.cfails onmaster.)Both pass with the fix.
🤖 Found during a source review with Claude Code
Fix in #453.