Fix decltype-call1.C with -std=c++1z.
authorJason Merrill <jason@redhat.com>
Mon, 7 Dec 2015 04:35:08 +0000 (23:35 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 7 Dec 2015 04:35:08 +0000 (23:35 -0500)
* parser.h (struct cp_token): Tell GTY that CPP_DECLTYPE uses
tree_check_value.
* parser.c (cp_parser_decltype): Use tree_check_value.
(saved_checks_value): New.
(cp_parser_nested_name_specifier_opt): Use it.
(cp_parser_template_id): Use it.
(cp_parser_simple_type_specifier): Use it.
(cp_parser_pre_parsed_nested_name_specifier): Use it.

From-SVN: r231353

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/cp/parser.h

index 9a8a2b58b04643b3d559bed56093db56e78ffbc8..ca9b97cba47a0fc0828fbedb5f5d0070ad75cad5 100644 (file)
@@ -1,5 +1,14 @@
 2015-12-06  Jason Merrill  <jason@redhat.com>
 
+       * parser.h (struct cp_token): Tell GTY that CPP_DECLTYPE uses
+       tree_check_value.
+       * parser.c (cp_parser_decltype): Use tree_check_value.
+       (saved_checks_value): New.
+       (cp_parser_nested_name_specifier_opt): Use it.
+       (cp_parser_template_id): Use it.
+       (cp_parser_simple_type_specifier): Use it.
+       (cp_parser_pre_parsed_nested_name_specifier): Use it.
+
        * semantics.c (finish_qualified_id_expr): Handle
        UNBOUND_CLASS_TEMPLATE.
 
index 1c7b1d5074792ebb93a196523be202ec15ed4e6e..ce5a21a759a36fa82f1f40726d4a95042c5c9bb6 100644 (file)
@@ -1008,6 +1008,28 @@ cp_lexer_next_token_is_decltype (cp_lexer *lexer)
   return token_is_decltype (t);
 }
 
+/* Called when processing a token with tree_check_value; perform or defer the
+   associated checks and return the value.  */
+
+static tree
+saved_checks_value (struct tree_check *check_value)
+{
+  /* Perform any access checks that were deferred.  */
+  vec<deferred_access_check, va_gc> *checks;
+  deferred_access_check *chk;
+  checks = check_value->checks;
+  if (checks)
+    {
+      int i;
+      FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
+       perform_or_defer_access_check (chk->binfo,
+                                      chk->decl,
+                                      chk->diag_decl, tf_warning_or_error);
+    }
+  /* Return the stored value.  */
+  return check_value->value;
+}
+
 /* Return a pointer to the Nth token in the token stream.  If N is 1,
    then this is precisely equivalent to cp_lexer_peek_token (except
    that it is not inline).  One would like to disallow that case, but
@@ -5818,7 +5840,7 @@ cp_parser_nested_name_specifier_opt (cp_parser *parser,
              token = cp_lexer_consume_token (parser->lexer);
              error_at (token->location, "decltype evaluates to %qT, "
                        "which is not a class or enumeration type",
-                       token->u.value);
+                       token->u.tree_check_value->value);
              parser->scope = error_mark_node;
              error_p = true;
              /* As below.  */
@@ -13016,7 +13038,7 @@ cp_parser_decltype (cp_parser *parser)
     {
       /* Already parsed.  */
       cp_lexer_consume_token (parser->lexer);
-      return start_token->u.value;
+      return saved_checks_value (start_token->u.tree_check_value);
     }
 
   /* Look for the `decltype' token.  */
@@ -13101,7 +13123,9 @@ cp_parser_decltype (cp_parser *parser)
   /* Replace the decltype with a CPP_DECLTYPE so we don't need to parse
      it again.  */
   start_token->type = CPP_DECLTYPE;
-  start_token->u.value = expr;
+  start_token->u.tree_check_value = ggc_cleared_alloc<struct tree_check> ();
+  start_token->u.tree_check_value->value = expr;
+  start_token->u.tree_check_value->checks = get_deferred_access_checks ();
   start_token->keyword = RID_MAX;
   cp_lexer_purge_tokens_after (parser->lexer, start_token);
 
@@ -14617,13 +14641,10 @@ cp_parser_template_id (cp_parser *parser,
                       enum tag_types tag_type,
                       bool is_declaration)
 {
-  int i;
   tree templ;
   tree arguments;
   tree template_id;
   cp_token_position start_of_id = 0;
-  deferred_access_check *chk;
-  vec<deferred_access_check, va_gc> *access_check;
   cp_token *next_token = NULL, *next_token_2 = NULL;
   bool is_identifier;
 
@@ -14632,22 +14653,8 @@ cp_parser_template_id (cp_parser *parser,
   next_token = cp_lexer_peek_token (parser->lexer);
   if (next_token->type == CPP_TEMPLATE_ID)
     {
-      struct tree_check *check_value;
-
-      /* Get the stored value.  */
-      check_value = cp_lexer_consume_token (parser->lexer)->u.tree_check_value;
-      /* Perform any access checks that were deferred.  */
-      access_check = check_value->checks;
-      if (access_check)
-       {
-         FOR_EACH_VEC_ELT (*access_check, i, chk)
-           perform_or_defer_access_check (chk->binfo,
-                                          chk->decl,
-                                          chk->diag_decl,
-                                          tf_warning_or_error);
-       }
-      /* Return the stored value.  */
-      return check_value->value;
+      cp_lexer_consume_token (parser->lexer);
+      return saved_checks_value (next_token->u.tree_check_value);
     }
 
   /* Avoid performing name lookup if there is no possibility of
@@ -15999,7 +16006,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
   if (token->type == CPP_DECLTYPE
       && cp_lexer_peek_nth_token (parser->lexer, 2)->type != CPP_SCOPE)
     {
-      type = token->u.value;
+      type = saved_checks_value (token->u.tree_check_value);
       if (decl_specs)
        {
          cp_parser_set_decl_spec_type (decl_specs, type,
@@ -27042,24 +27049,12 @@ cp_parser_optional_template_keyword (cp_parser *parser)
 static void
 cp_parser_pre_parsed_nested_name_specifier (cp_parser *parser)
 {
-  int i;
   struct tree_check *check_value;
-  deferred_access_check *chk;
-  vec<deferred_access_check, va_gc> *checks;
 
   /* Get the stored value.  */
   check_value = cp_lexer_consume_token (parser->lexer)->u.tree_check_value;
-  /* Perform any access checks that were deferred.  */
-  checks = check_value->checks;
-  if (checks)
-    {
-      FOR_EACH_VEC_SAFE_ELT (checks, i, chk)
-       perform_or_defer_access_check (chk->binfo,
-                                      chk->decl,
-                                      chk->diag_decl, tf_warning_or_error);
-    }
   /* Set the scope from the stored value.  */
-  parser->scope = check_value->value;
+  parser->scope = saved_checks_value (check_value);
   parser->qualifying_scope = check_value->qualifying_scope;
   parser->object_scope = NULL_TREE;
 }
index a6b8e74feb6e621b32c808cb51bdddc453917568..891dd4143efedce9a1a3faa41406b325307f01fc 100644 (file)
@@ -63,11 +63,13 @@ struct GTY (()) cp_token {
   location_t location;
   /* The value associated with this token, if any.  */
   union cp_token_value {
-    /* Used for CPP_NESTED_NAME_SPECIFIER and CPP_TEMPLATE_ID.  */
+    /* Used for compound tokens such as CPP_NESTED_NAME_SPECIFIER.  */
     struct tree_check* GTY((tag ("1"))) tree_check_value;
     /* Use for all other tokens.  */
     tree GTY((tag ("0"))) value;
-  } GTY((desc ("(%1.type == CPP_TEMPLATE_ID) || (%1.type == CPP_NESTED_NAME_SPECIFIER)"))) u;
+  } GTY((desc ("(%1.type == CPP_TEMPLATE_ID)"
+              "|| (%1.type == CPP_NESTED_NAME_SPECIFIER)"
+              "|| (%1.type == CPP_DECLTYPE)"))) u;
 };