On Tue, Jan 26, 2016 at 3:17 PM, Jakub Jelinek <ja...@redhat.com> wrote: > Hi! > > If as in the testcase below a VAR_DECL has error_mark_node type > (and that unfortunately happens (and has to) quite late, at the end of > parsing the TU), canonicalize_constructor_val can ICE on that, because it > will try to fold convert something to error_mark_node type. > > Fixed by giving up in that case. > The patch also cleans up the change that introduced the error_mark_node in > there, to use FOR_EACH_VEC_ELT. > > Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?
Ok. Thanks, Richard. > 2016-01-26 Jakub Jelinek <ja...@redhat.com> > > PR tree-optimization/69483 > * gimple-fold.c (canonicalize_constructor_val): Return NULL > if base has error_mark_node type. > > * c-parser.c (c_parser_translation_unit): Use FOR_EACH_VEC_ELT. > > * gcc.dg/pr69483.c: New test. > * g++.dg/opt/pr69483.C: New test. > > --- gcc/gimple-fold.c.jj 2016-01-08 21:48:36.000000000 +0100 > +++ gcc/gimple-fold.c 2016-01-26 10:54:12.142355308 +0100 > @@ -195,6 +195,8 @@ canonicalize_constructor_val (tree cval, > || TREE_CODE (base) == FUNCTION_DECL) > && !can_refer_decl_in_current_unit_p (base, from_decl)) > return NULL_TREE; > + if (TREE_TYPE (base) == error_mark_node) > + return NULL_TREE; > if (TREE_CODE (base) == VAR_DECL) > TREE_ADDRESSABLE (base) = 1; > else if (TREE_CODE (base) == FUNCTION_DECL) > --- gcc/c/c-parser.c.jj 2016-01-21 00:41:47.000000000 +0100 > +++ gcc/c/c-parser.c 2016-01-26 10:59:30.104941374 +0100 > @@ -1431,15 +1431,14 @@ c_parser_translation_unit (c_parser *par > while (c_parser_next_token_is_not (parser, CPP_EOF)); > } > > - for (unsigned i = 0; i < incomplete_record_decls.length (); ++i) > - { > - tree decl = incomplete_record_decls[i]; > - if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != > error_mark_node) > - { > - error ("storage size of %q+D isn%'t known", decl); > - TREE_TYPE (decl) = error_mark_node; > - } > - } > + unsigned int i; > + tree decl; > + FOR_EACH_VEC_ELT (incomplete_record_decls, i, decl) > + if (DECL_SIZE (decl) == NULL_TREE && TREE_TYPE (decl) != error_mark_node) > + { > + error ("storage size of %q+D isn%'t known", decl); > + TREE_TYPE (decl) = error_mark_node; > + } > } > > /* Parse an external declaration (C90 6.7, C99 6.9). > --- gcc/testsuite/gcc.dg/pr69483.c.jj 2016-01-26 11:02:41.152289108 +0100 > +++ gcc/testsuite/gcc.dg/pr69483.c 2016-01-26 11:02:20.000000000 +0100 > @@ -0,0 +1,6 @@ > +/* PR tree-optimization/69483 */ > +/* { dg-do compile } */ > + > +struct T { struct S *a; }; > +struct S b; /* { dg-error "storage size of 'b' isn't known" } */ > +struct T c = { &b }; > --- gcc/testsuite/g++.dg/opt/pr69483.C.jj 2016-01-26 11:06:03.375481313 > +0100 > +++ gcc/testsuite/g++.dg/opt/pr69483.C 2016-01-26 11:03:20.000000000 +0100 > @@ -0,0 +1,6 @@ > +// PR tree-optimization/69483 > +// { dg-do compile } > + > +struct T { struct S *a; }; > +struct S b; // { dg-error "aggregate 'S b' has incomplete type and cannot be > defined" } > +struct T c = { &b }; > > Jakub