]> gcc.gnu.org Git - gcc.git/blobdiff - gcc/cp/parser.c
c++: Don't try to parse a function declaration as deduction guide [PR97663]
[gcc.git] / gcc / cp / parser.c
index 00e950d2e9370abbe7057a10bdb3f1eb1cc29fde..64dde058dd32173f9d3a610ac576a92cf1ebb7d9 100644 (file)
@@ -10907,7 +10907,12 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
       /* Parse optional exception specification.  */
       exception_spec = cp_parser_exception_specification_opt (parser);
 
-      std_attrs = cp_parser_std_attribute_spec_seq (parser);
+      /* GCC 8 accepted attributes here, and this is the place for standard
+        C++11 attributes that appertain to the function type.  */
+      if (cp_next_tokens_can_be_gnu_attribute_p (parser))
+       gnu_attrs = cp_parser_gnu_attributes_opt (parser);
+      else
+       std_attrs = cp_parser_std_attribute_spec_seq (parser);
 
       /* Parse optional trailing return type.  */
       if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF))
@@ -10916,8 +10921,10 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
           return_type = cp_parser_trailing_type_id (parser);
         }
 
+      /* Also allow GNU attributes at the very end of the declaration, the
+        usual place for GNU attributes.  */
       if (cp_next_tokens_can_be_gnu_attribute_p (parser))
-       gnu_attrs = cp_parser_gnu_attributes_opt (parser);
+       gnu_attrs = chainon (gnu_attrs, cp_parser_gnu_attributes_opt (parser));
 
       /* The function parameters must be in scope all the way until after the
          trailing-return-type in case of decltype.  */
@@ -13495,7 +13502,7 @@ cp_parser_simple_declaration (cp_parser* parser,
            if ((decl != error_mark_node
                 && DECL_INITIAL (decl) != error_mark_node)
                || cp_parser_uncommitted_to_tentative_parse_p (parser))
-             cp_parser_error (parser, "expected %<,%> or %<;%>");
+             cp_parser_error (parser, "expected %<;%>");
            /* Skip tokens until we reach the end of the statement.  */
            cp_parser_skip_to_end_of_statement (parser);
            /* If the next token is now a `;', consume it.  */
@@ -18631,7 +18638,9 @@ cp_parser_elaborated_type_specifier (cp_parser* parser,
       if (TREE_CODE (type) == TYPENAME_TYPE)
        warning (OPT_Wattributes,
                 "attributes ignored on uninstantiated type");
-      else if (tag_type != enum_type && CLASSTYPE_TEMPLATE_INSTANTIATION (type)
+      else if (tag_type != enum_type
+              && TREE_CODE (type) != BOUND_TEMPLATE_TEMPLATE_PARM
+              && CLASSTYPE_TEMPLATE_INSTANTIATION (type)
               && ! processing_explicit_instantiation)
        warning (OPT_Wattributes,
                 "attributes ignored on template instantiation");
@@ -20260,6 +20269,7 @@ cp_parser_init_declarator (cp_parser* parser,
     {
       /* Handle C++17 deduction guides.  */
       if (!decl_specifiers->type
+         && !decl_specifiers->any_type_specifiers_p
          && ctor_dtor_or_conv_p <= 0
          && cxx_dialect >= cxx17)
        {
@@ -32608,7 +32618,11 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
                  parser->colon_corrects_to_scope_p = false;
                  cp_lexer_consume_token (parser->lexer);
                  if (!cp_lexer_next_token_is (parser->lexer, CPP_COLON))
-                   low_bound = cp_parser_expression (parser);
+                   {
+                     low_bound = cp_parser_expression (parser);
+                     /* Later handling is not prepared to see through these.  */
+                     gcc_checking_assert (!location_wrapper_p (low_bound));
+                   }
                  if (!colon)
                    parser->colon_corrects_to_scope_p
                      = saved_colon_corrects_to_scope_p;
@@ -32628,7 +32642,11 @@ cp_parser_omp_var_list_no_open (cp_parser *parser, enum omp_clause_code kind,
                        cp_parser_commit_to_tentative_parse (parser);
                      if (!cp_lexer_next_token_is (parser->lexer,
                                                   CPP_CLOSE_SQUARE))
-                       length = cp_parser_expression (parser);
+                       {
+                         length = cp_parser_expression (parser);
+                         /* Later handling is not prepared to see through these.  */
+                         gcc_checking_assert (!location_wrapper_p (length));
+                       }
                    }
                  /* Look for the closing `]'.  */
                  if (!cp_parser_require (parser, CPP_CLOSE_SQUARE,
@@ -35050,7 +35068,7 @@ cp_parser_oacc_clause_async (cp_parser *parser, tree list)
       matching_parens parens;
       parens.consume_open (parser);
 
-      t = cp_parser_expression (parser);
+      t = cp_parser_assignment_expression (parser);
       if (t == error_mark_node
          || !parens.require_close (parser))
        cp_parser_skip_to_closing_parenthesis (parser, /*recovering=*/true,
@@ -35079,6 +35097,9 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
   tree clauses = NULL;
   bool first = true;
 
+  /* Don't create location wrapper nodes within OpenACC clauses.  */
+  auto_suppress_location_wrappers sentinel;
+
   while (cp_lexer_next_token_is_not (parser->lexer, CPP_PRAGMA_EOL))
     {
       location_t here;
@@ -37820,9 +37841,9 @@ cp_parser_omp_parallel (cp_parser *parser, cp_token *pragma_tok,
          cp_parser_end_omp_structured_block (parser, save);
          stmt = finish_omp_parallel (cclauses[C_OMP_CLAUSE_SPLIT_PARALLEL],
                                      block);
-         OMP_PARALLEL_COMBINED (stmt) = 1;
          if (ret == NULL_TREE)
            return ret;
+         OMP_PARALLEL_COMBINED (stmt) = 1;
          return stmt;
        }
       else if (!flag_openmp)  /* flag_openmp_simd  */
@@ -38760,6 +38781,10 @@ check_clauses:
 static tree
 cp_parser_oacc_cache (cp_parser *parser, cp_token *pragma_tok)
 {
+  /* Don't create location wrapper nodes within 'OMP_CLAUSE__CACHE_'
+     clauses.  */
+  auto_suppress_location_wrappers sentinel;
+
   tree stmt, clauses;
 
   clauses = cp_parser_omp_var_list (parser, OMP_CLAUSE__CACHE_, NULL_TREE);
This page took 0.056532 seconds and 5 git commands to generate.