Skip to content

c2mir: two statement-expression value bugs (struct slot reuse + post-inc/dec in value context) #452

Description

@derekbsnider

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions