The C++ FE builds from the following testcase:

typedef long unsigned int size_t;
void* operator new(size_t, void* __p);
class locale {
public:
    class facet;
    const facet** _M_facets;
    locale(size_t);
};
typedef char fake_facet_vec[128];
fake_facet_vec facet_vec;
locale::locale(size_t __refs)
{
  _M_facets = new (&facet_vec) const facet*;
}

the following trees with -fstrict-aliasing:

{
  <<cleanup_point <<< Unknown tree: expr_stmt
  (void) (((struct locale *) this)->_M_facets = (<<<change_dynamic_type (const
struct facet * *) TARGET_EXPR <D.2102, &facet_vec>)>>>, (const struct facet *
*) operator new (8, (void *) TARGET_EXPR <D.2102, &facet_vec>);)) >>>
>>;
}

where the TARGET_EXPR <D.2102, &facet_vec> tree is shared, and this is the
only reason the code works after gimplifying and it does not ICE during
gimplification.  If you unshare the trees the gimplifier ICEs in
gimple_add_tmp_var, at gimplify.c:827 because D.2102 is used twice as the
target of a TARGET_EXPR.

Obviously the IL construct emitted by the frontend is completely bogus in
this case.


-- 
           Summary: Invalid tree sharing with CHANGE_DYNAMIC_TYPE_EXPR
           Product: gcc
           Version: 4.4.0
            Status: UNCONFIRMED
          Keywords: wrong-code
          Severity: normal
          Priority: P3
         Component: c++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: rguenth at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=37847

Reply via email to