------- Additional Comments From mmitchel at gcc dot gnu dot org 2005-03-04 08:13 ------- (Of course, the root cause of this problem is that "fold" is being called before gimplification, which Nathan and I have sermonized about previously.)
There's interesting interplay between this PR and PR 20280. In particular, RTH's proposed transformation in Comment #8 is invalid if A and B are bit-fields, because the address of a bitfield cannot be taken. Consider: struct S { int i : 7; }; S s; extern int &b; const int &a = (x ? s.i : b); This cannot be transformed into: int *a = &*((x ? t = &s.i : t = &*b), t); as per Comment #8. Indeed fold transforms ((s.i > i)? s.i : i) into MAX_EXPR (s.i, i) in this program: struct S { int i : 7; }; S s; extern int &i; bool b; void g() { ((s.i > i) ? s.i : i) = 3; } That happens to work only because of the hack where we allow MAX_EXPR as an lvalue in an assignment in build_modify_expr if neither argument has side-effects. (We recreate the COND_EXPR there.) This change went in as the fix for PR 7503. Roger, I think you need the same hack where you bind COND_EXPRs to references, take their addresses, etc. In fact, you should probably just make real_lvalue_p accept MAX_EXPRs with side-effect free operands. And, then, wherever we need lvalues do the conversion that you presently do in build_modify_expr. That's consistent with your "MAX_EXPRs are just the canonical form of certain COND_EXPRs" logic. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=19199