http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54828
Jakub Jelinek <jakub at gcc dot gnu.org> changed: What |Removed |Added ---------------------------------------------------------------------------- CC| |jakub at gcc dot gnu.org --- Comment #3 from Jakub Jelinek <jakub at gcc dot gnu.org> 2012-10-23 09:07:44 UTC --- That workaround is definitely wrong. The problem is that variably_modified_type_p returns false for the VLA ARRAY_TYPE when running clone_body to clone the abstract ctor into __base_ctor, because the TYPE_SIZE is (bitsizetype) ((sizetype) (SAVE_EXPR <(ssizetype) v + -1>) + 1) * 8 and v isn't a auto_var_in_fn_p (it is a global variable). As variably_modified_type_p returns false, we don't remap the type during cloning, and then we end up sharing the same ARRAY_TYPE in between the abstract ctor and base (or even base and comp) ctor, then in one of the real ctors (base and/or comp) the type is gimplified and suddenly it is variably_modified_type_p, but as the type is shared, we have a local VAR_DECL of one of the ctors as TYPE_SIZE{,_UNIT} of the array type also in the other real ctor and in the abstract ctor. Better testcase is perhaps: struct T { T (); virtual ~T (); }; struct S : public virtual T { S (); virtual ~S (); }; int v; void foo (char *); S::S () { char s[v]; foo (s); } So, I wonder if either variably_modified_type_p with fn != NULL shouldn't take into account !TYPE_SIZES_GIMPLIFIED (assume if gimplify_one_sizepos would gimplify_expr it, it would turn it into auto_var_in_fn_p containing it), or if tree-inline.c (remap_type) just shouldn't call variably_modified_type_p with fn == NULL if !TYPE_SIZES_GIMPLIFIED: --- gcc/tree-inline.c.jj 2012-10-05 21:25:36.000000000 +0200 +++ gcc/tree-inline.c 2012-10-23 11:05:05.099212208 +0200 @@ -504,7 +504,8 @@ remap_type (tree type, copy_body_data *i return *node; /* The type only needs remapping if it's variably modified. */ - if (! variably_modified_type_p (type, id->src_fn)) + if (! variably_modified_type_p (type, TYPE_SIZES_GIMPLIFIED (type) + ? id->src_fn : NULL_TREE)) { insert_decl_map (id, type, type); return type; seems to work for this testcase, but haven't tested it more than that. I hope the inliner is usually used on gimplified functions these days, if the only exception is the body cloning of ctors/dtors in C++ FE and if lambdas aren't handled as normal C nested functions (and C++ doesn't have them), this could perhaps work.