------- Comment #2 from rguenth at gcc dot gnu dot org 2008-02-17 16:19 ------- There are a few different cases. For
int foo(void); void *a(void *p) { return (int (*)[foo()])p; } the frontend already got rid of the intermediate casts (and side-effects). For int foo(void); void a(void *p) { (int (*)[foo()])p; } the frontend retains the cast and the side-effects, but the gimplifier removes them. One error is certainly: Breakpoint 3, fold_unary (code=NOP_EXPR, type=0xb7cee2d8, op0=0xb7d46140) at /home/richard/src/trunk/gcc/fold-const.c:7932 7932 enum tree_code_class kind = TREE_CODE_CLASS (code); (int[0:(unsigned int) (SAVE_EXPR <foo ()> + -1)] *) p (gdb) call debug_generic_expr (type) void * (gdb) print op0->base.side_effects_flag $1 = 0 that is, the conversion is not marked as producing side-effects (possibly because the side-effect is wrapped in a SAVE_EXPR). It is also not clear to me whether we should do so (wrap the call inside a SAVE_EXPR). What is supposed to happen for int foo(void); void a(void *p) { (int (*)[foo()])p; (int (*)[foo()])p; } ? Is foo supposed to be called twice? I think the burden should be on the side of the frontend to instead emit a COMPOUND_EXPR like ( SAVE_EXPR<foo()>, (int (*)[SAVE_EXPR<foo()>])p ) here. At least marking the whole conversion as having no side-effects doesn't tell the truth really, likewise if SAVE_EXPRs have no side-effects, as that wouldn't guarantee it is evaluated at least once. But maybe I am missing parts of GCC history here. -- rguenth at gcc dot gnu dot org changed: What |Removed |Added ---------------------------------------------------------------------------- Priority|P3 |P2 http://gcc.gnu.org/bugzilla/show_bug.cgi?id=35198