------- Additional Comments From ebotcazou at gcc dot gnu dot org 2005-02-24 16:49 ------- Hum... again a consequence of the C++ front-end not setting TREE_SIDE_EFFECTS on every CALL_EXPR, like the C front-end. The sequence of events is as follows:
1. fn1()->s -= 1 is expanded to the 3-operand form in build_modify_expr { /* A binary op has been requested. Combine the old LHS value with the RHS producing the value we should actually store into the LHS. */ my_friendly_assert (!PROMOTES_TO_AGGR_TYPE (lhstype, REFERENCE_TYPE), 978652); lhs = stabilize_reference (lhs); newrhs = cp_build_binary_op (modifycode, lhs, rhs); if (newrhs == error_mark_node) { error (" in evaluation of `%Q(%#T, %#T)'", modifycode, TREE_TYPE (lhs), TREE_TYPE (rhs)); return error_mark_node; } /* Now it looks like a plain assignment. */ modifycode = NOP_EXPR; } Note the call to stabilize_reference. However, it doesn't stabilize anything here because the lhs is advertised as having no side-effects. 2. The tree-inliner inlines the call. Since the same tree is referenced twice in the expression, the inlined body is also referenced twice is the expression and, therefore, expanded twice to RTL. However labels are not expanded multiple times but reused, so the second block of RTL ends up referencing the first and all hell breaks loose. At this point my conclusion is that the only safe approach is that of the C front-end. Mark, do you recall having reviewed the initial patch (see comment #22)? What do you think? Thanks in advance. -- What |Removed |Added ---------------------------------------------------------------------------- CC| |mark at codesourcery dot com http://gcc.gnu.org/bugzilla/show_bug.cgi?id=17972