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

Reply via email to