Hi!

cp_parser_parenthesized_expression_list creates expression_list in GC
memory; if it is called when current_function_decl is NULL, there might be
ggc_collect in the middle of the parsing and collect that vector.

Fixed by temporarily bumping function_depth.  Or should that be done in some
other function from this function down to the ggc_collect (the PR has full
backtrace when that happens)?

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2018-12-18  Jakub Jelinek  <ja...@redhat.com>

        PR c++/88180
        * parser.c (cp_parser_parenthesized_expression_list): Temporarily
        bump function_depth if current_function_decl is NULL.

        * g++.dg/parse/pr88180.C: New test.

--- gcc/cp/parser.c.jj  2018-12-14 23:31:50.530979326 +0100
+++ gcc/cp/parser.c     2018-12-18 19:48:45.218893963 +0100
@@ -7794,6 +7794,11 @@ cp_parser_parenthesized_expression_list
     = parser->greater_than_is_operator_p;
   parser->greater_than_is_operator_p = true;
 
+  /* Avoid GC of the expression_list while parsing the expression
+     list.  */
+  if (!current_function_decl)
+    ++function_depth;
+
   cp_expr expr (NULL_TREE);
 
   /* Consume expressions until there are no more.  */
@@ -7899,6 +7904,10 @@ cp_parser_parenthesized_expression_list
        {
          parser->greater_than_is_operator_p
            = saved_greater_than_is_operator_p;
+
+         if (!current_function_decl)
+           --function_depth;
+
          return NULL;
        }
     }
@@ -7906,6 +7915,9 @@ cp_parser_parenthesized_expression_list
   parser->greater_than_is_operator_p
     = saved_greater_than_is_operator_p;
 
+  if (!current_function_decl)
+    --function_depth;
+
   if (identifier)
     vec_safe_insert (expression_list, 0, identifier);
 
--- gcc/testsuite/g++.dg/parse/pr88180.C.jj     2018-12-18 19:51:26.208290671 
+0100
+++ gcc/testsuite/g++.dg/parse/pr88180.C        2018-12-18 19:49:55.242761535 
+0100
@@ -0,0 +1,12 @@
+// PR c++/88180
+// { dg-do compile }
+// { dg-options "--param ggc-min-heapsize=1024" }
+
+struct d {
+  static d *b;
+} * d::b(__builtin_offsetof(struct { // { dg-error "types may not be defined" }
+  int i;
+  struct a { // { dg-error "types may not be defined" }
+    int c() { return .1f; }
+  };
+}, i));

        Jakub

Reply via email to