struct S { S () : d(1.0) {} S (const double &x) : d(x) {} S (const S &x) : d(x.d) {} const S &operator= (const S &x) { d = x.d; return *this; } bool operator< (const S &x) const { return d < x.d; } double d; };
S foo (S a, S b) { S c = ({ (a < b) ? a : b; }); return c; } extern "C" void abort (); int main (void) { S a = 6.0, b = 8.0, c = 10.0, r; r = foo (a, b); if (r.d != 6.0) abort (); r = foo (c, a); if (r.d != 6.0) abort (); r = foo (c, b); if (r.d != 8.0) abort (); return 0; } ICEs in cp_expr_size at -O0 and is miscompiled at -O2. After gimplification foo looks like: S foo(S, S) (a, b) { struct S & c.0; struct S D.2401; bool D.2405; struct S c; (void) 0; c.0 = <retval>; D.2405 = operator< (a, b); *c.0 = D.2401; return <retval>; } so D.2401 is undefined and D.2405 is unused. Before gimplification it is: { struct S c; (void) 0; <<cleanup_point <<< Unknown tree: expr_stmt (void) (*<retval> = TARGET_EXPR <D.2401, <<cleanup_point <<< Unknown tree: expr_stmt if (operator< ((struct S *) a, (struct S &) (struct S *) (struct S *) b)) { (void) *a; } else { (void) *b; } >>> >>>) >>> >>; <<cleanup_point return <retval>>>; } which looks ok. With GCC 3.4.x the test passed at all optimization levels. -- Summary: [4.0/4.1/4.2 Regression] ICE in cp_expr_size or miscompilation Product: gcc Version: 4.1.1 Status: UNCONFIRMED Severity: critical Priority: P3 Component: c++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: jakub at gcc dot gnu dot org http://gcc.gnu.org/bugzilla/show_bug.cgi?id=27115