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