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.

Reply via email to