------- 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