]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/cp/parser.c
Wrap option names in gcc internal messages with %< and %>.
[thirdparty/gcc.git] / gcc / cp / parser.c
index 16f2a32bc0bffc0946bd60d9f624c6bea242565f..f95111169ed3ebfe1c6ac42c2f33882faed2ff49 100644 (file)
@@ -2251,7 +2251,7 @@ static cp_expr cp_parser_initializer_clause
 static cp_expr cp_parser_braced_list
   (cp_parser*, bool*);
 static vec<constructor_elt, va_gc> *cp_parser_initializer_list
-  (cp_parser *, bool *);
+  (cp_parser *, bool *, bool *);
 
 static void cp_parser_ctor_initializer_opt_and_function_body
   (cp_parser *, bool);
@@ -3288,7 +3288,7 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id,
                decl);
       if (DECL_CLASS_TEMPLATE_P (decl) && cxx_dialect < cxx17)
        inform (location, "class template argument deduction is only available "
-               "with -std=c++17 or -std=gnu++17");
+               "with %<-std=c++17%> or %<-std=gnu++17%>");
       inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl);
     }
   else if (TREE_CODE (id) == BIT_NOT_EXPR)
@@ -3322,17 +3322,17 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id,
         The user should have said "typename A<T>::X".  */
       if (cxx_dialect < cxx11 && id == ridpointers[(int)RID_CONSTEXPR])
        inform (location, "C++11 %<constexpr%> only available with "
-               "-std=c++11 or -std=gnu++11");
+               "%<-std=c++11%> or %<-std=gnu++11%>");
       else if (cxx_dialect < cxx11 && id == ridpointers[(int)RID_NOEXCEPT])
        inform (location, "C++11 %<noexcept%> only available with "
-               "-std=c++11 or -std=gnu++11");
+               "%<-std=c++11%> or %<-std=gnu++11%>");
       else if (cxx_dialect < cxx11
               && TREE_CODE (id) == IDENTIFIER_NODE
               && id_equal (id, "thread_local"))
        inform (location, "C++11 %<thread_local%> only available with "
-               "-std=c++11 or -std=gnu++11");
+               "%<-std=c++11%> or %<-std=gnu++11%>");
       else if (!flag_concepts && id == ridpointers[(int)RID_CONCEPT])
-       inform (location, "%<concept%> only available with -fconcepts");
+       inform (location, "%<concept%> only available with %<-fconcepts%>");
       else if (processing_template_decl && current_class_type
               && TYPE_BINFO (current_class_type))
        {
@@ -4551,7 +4551,7 @@ cp_parser_userdef_numeric_literal (cp_parser *parser)
                "GNU built-in suffix");
     }
   else if (!ext)
-    inform (token->location, "use -fext-numeric-literals "
+    inform (token->location, "use %<-fext-numeric-literals%> "
            "to enable more built-in suffixes");
 
   if (kind == DK_ERROR)
@@ -5331,7 +5331,7 @@ cp_parser_primary_expression (cp_parser *parser,
                && cxx_dialect < cxx17
                && !in_system_header_at (input_location))
              pedwarn (input_location, 0, "fold-expressions only available "
-                      "with -std=c++17 or -std=gnu++17");
+                      "with %<-std=c++17%> or %<-std=gnu++17%>");
          }
        else
          /* Let the front end know that this expression was
@@ -5976,6 +5976,7 @@ cp_parser_unqualified_id (cp_parser* parser,
        tree object_scope;
        tree scope;
        bool done;
+       location_t tilde_loc = token->location;
 
        /* Consume the `~' token.  */
        cp_lexer_consume_token (parser->lexer);
@@ -6038,9 +6039,18 @@ cp_parser_unqualified_id (cp_parser* parser,
          }
        gcc_assert (!scope || TYPE_P (scope));
 
+       token = cp_lexer_peek_token (parser->lexer);
+
+       /* Create a location with caret == start at the tilde,
+          finishing at the end of the peeked token, e.g:
+          ~token
+          ^~~~~~.  */
+       location_t loc
+         = make_location (tilde_loc, tilde_loc, token->location);
+
        /* If the name is of the form "X::~X" it's OK even if X is a
           typedef.  */
-       token = cp_lexer_peek_token (parser->lexer);
+
        if (scope
            && token->type == CPP_NAME
            && (cp_lexer_peek_nth_token (parser->lexer, 2)->type
@@ -6050,18 +6060,18 @@ cp_parser_unqualified_id (cp_parser* parser,
                    && constructor_name_p (token->u.value, scope))))
          {
            cp_lexer_consume_token (parser->lexer);
-           return build_nt (BIT_NOT_EXPR, scope);
+           return cp_expr (build_nt (BIT_NOT_EXPR, scope), loc);
          }
 
        /* ~auto means the destructor of whatever the object is.  */
        if (cp_parser_is_keyword (token, RID_AUTO))
          {
            if (cxx_dialect < cxx14)
-             pedwarn (input_location, 0,
+             pedwarn (loc, 0,
                       "%<~auto%> only available with "
-                      "-std=c++14 or -std=gnu++14");
+                      "%<-std=c++14%> or %<-std=gnu++14%>");
            cp_lexer_consume_token (parser->lexer);
-           return build_nt (BIT_NOT_EXPR, make_auto ());
+           return cp_expr (build_nt (BIT_NOT_EXPR, make_auto (), loc));
          }
 
        /* If there was an explicit qualification (S::~T), first look
@@ -6152,7 +6162,7 @@ cp_parser_unqualified_id (cp_parser* parser,
                type_decl = cp_parser_identifier (parser);
                if (type_decl != error_mark_node)
                  type_decl = build_nt (BIT_NOT_EXPR, type_decl);
-               return type_decl;
+               return cp_expr (type_decl, loc);
              }
          }
        /* If an error occurred, assume that the name of the
@@ -6168,7 +6178,7 @@ cp_parser_unqualified_id (cp_parser* parser,
        if (declarator_p && scope && !check_dtor_name (scope, type_decl))
          {
            if (!cp_parser_uncommitted_to_tentative_parse_p (parser))
-             error_at (token->location,
+             error_at (loc,
                        "declaration of %<~%T%> as member of %qT",
                        type_decl, scope);
            cp_parser_simulate_error (parser);
@@ -6183,11 +6193,11 @@ cp_parser_unqualified_id (cp_parser* parser,
            && !DECL_IMPLICIT_TYPEDEF_P (type_decl)
            && !DECL_SELF_REFERENCE_P (type_decl)
            && !cp_parser_uncommitted_to_tentative_parse_p (parser))
-         error_at (token->location,
+         error_at (loc,
                    "typedef-name %qD used as destructor declarator",
                    type_decl);
 
-       return build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl));
+       return cp_expr (build_nt (BIT_NOT_EXPR, TREE_TYPE (type_decl), loc));
       }
 
     case CPP_KEYWORD:
@@ -7993,7 +8003,7 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
       if (cxx_dialect < cxx14)
        pedwarn (input_location, 0,
                 "%<~auto%> only available with "
-                "-std=c++14 or -std=gnu++14");
+                "%<-std=c++14%> or %<-std=gnu++14%>");
       cp_lexer_consume_token (parser->lexer);
       cp_lexer_consume_token (parser->lexer);
       *scope = NULL_TREE;
@@ -10090,7 +10100,7 @@ cp_parser_builtin_offsetof (cp_parser *parser)
   {
     const char *saved_message = parser->type_definition_forbidden_message;
     parser->type_definition_forbidden_message
-      = G_("types may not be defined within __builtin_offsetof");
+      = G_("types may not be defined within %<__builtin_offsetof%>");
     type = cp_parser_type_id (parser);
     parser->type_definition_forbidden_message = saved_message;
   }
@@ -10380,7 +10390,7 @@ cp_parser_lambda_expression (cp_parser* parser)
        {
          error_at (LAMBDA_EXPR_LOCATION (lambda_expr),
                    "lambda-expression in unevaluated context"
-                   " only available with -std=c++2a or -std=gnu++2a");
+                   " only available with %<-std=c++2a%> or %<-std=gnu++2a%>");
          token->error_reported = true;
        }
       ok = false;
@@ -10390,7 +10400,7 @@ cp_parser_lambda_expression (cp_parser* parser)
       if (!token->error_reported)
        {
          error_at (token->location, "lambda-expression in template-argument"
-                   " only available with -std=c++2a or -std=gnu++2a");
+                   " only available with %<-std=c++2a%> or %<-std=gnu++2a%>");
          token->error_reported = true;
        }
       ok = false;
@@ -10587,7 +10597,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
          location_t loc = cp_lexer_peek_token (parser->lexer)->location;
          if (cxx_dialect < cxx17)
            pedwarn (loc, 0, "%<*this%> capture only available with "
-                            "-std=c++17 or -std=gnu++17");
+                            "%<-std=c++17%> or %<-std=gnu++17%>");
          cp_lexer_consume_token (parser->lexer);
          cp_lexer_consume_token (parser->lexer);
          add_capture (lambda_expr,
@@ -10604,7 +10614,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
          location_t loc = cp_lexer_peek_token (parser->lexer)->location;
          if (cxx_dialect < cxx2a)
            pedwarn (loc, 0, "pack init-capture only available with "
-                            "-std=c++2a or -std=gnu++2a");
+                            "%<-std=c++2a%> or %<-std=gnu++2a%>");
          cp_lexer_consume_token (parser->lexer);
          init_pack_expansion = true;
        }
@@ -10643,7 +10653,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
          if (cxx_dialect < cxx14)
            pedwarn (input_location, 0,
                     "lambda capture initializers "
-                    "only available with -std=c++14 or -std=gnu++14");
+                    "only available with %<-std=c++14%> or %<-std=gnu++14%>");
          capture_init_expr = cp_parser_initializer (parser, &direct,
                                                     &non_constant, true);
          explicit_init_p = true;
@@ -10781,11 +10791,11 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
       if (cxx_dialect < cxx14)
        pedwarn (parser->lexer->next_token->location, 0,
                 "lambda templates are only available with "
-                "-std=c++14 or -std=gnu++14");
+                "%<-std=c++14%> or %<-std=gnu++14%>");
       else if (cxx_dialect < cxx2a)
        pedwarn (parser->lexer->next_token->location, OPT_Wpedantic,
                 "lambda templates are only available with "
-                "-std=c++2a or -std=gnu++2a");
+                "%<-std=c++2a%> or %<-std=gnu++2a%>");
 
       cp_lexer_consume_token (parser->lexer);
 
@@ -10880,7 +10890,8 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
            = lambda_specs.locations[ds_constexpr];
        else
          error_at (lambda_specs.locations[ds_constexpr], "%<constexpr%> "
-                   "lambda only available with -std=c++17 or -std=gnu++17");
+                   "lambda only available with %<-std=c++17%> or "
+                   "%<-std=gnu++17%>");
       }
 
     p = obstack_alloc (&declarator_obstack, 0);
@@ -11060,7 +11071,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
 {
   tree statement, std_attrs = NULL_TREE;
   cp_token *token;
-  location_t statement_location, attrs_location;
+  location_t statement_location, attrs_loc;
 
  restart:
   if (if_p != NULL)
@@ -11069,13 +11080,19 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
   statement = NULL_TREE;
 
   saved_token_sentinel saved_tokens (parser->lexer);
-  attrs_location = cp_lexer_peek_token (parser->lexer)->location;
+  attrs_loc = cp_lexer_peek_token (parser->lexer)->location;
   if (c_dialect_objc ())
     /* In obj-c++, seeing '[[' might be the either the beginning of
        c++11 attributes, or a nested objc-message-expression.  So
        let's parse the c++11 attributes tentatively.  */
     cp_parser_parse_tentatively (parser);
   std_attrs = cp_parser_std_attribute_spec_seq (parser);
+  if (std_attrs)
+    {
+      location_t end_loc
+       = cp_lexer_previous_token (parser->lexer)->location;
+      attrs_loc = make_location (attrs_loc, attrs_loc, end_loc);
+    }
   if (c_dialect_objc ())
     {
       if (!cp_parser_parse_definitely (parser))
@@ -11107,14 +11124,14 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
 
        case RID_IF:
        case RID_SWITCH:
-         std_attrs = process_stmt_hotness_attribute (std_attrs);
+         std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
          statement = cp_parser_selection_statement (parser, if_p, chain);
          break;
 
        case RID_WHILE:
        case RID_DO:
        case RID_FOR:
-         std_attrs = process_stmt_hotness_attribute (std_attrs);
+         std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
          statement = cp_parser_iteration_statement (parser, if_p, false, 0);
          break;
 
@@ -11122,7 +11139,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
        case RID_CONTINUE:
        case RID_RETURN:
        case RID_GOTO:
-         std_attrs = process_stmt_hotness_attribute (std_attrs);
+         std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
          statement = cp_parser_jump_statement (parser);
          break;
 
@@ -11132,12 +11149,12 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
        case RID_AT_FINALLY:
        case RID_AT_SYNCHRONIZED:
        case RID_AT_THROW:
-         std_attrs = process_stmt_hotness_attribute (std_attrs);
+         std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
          statement = cp_parser_objc_statement (parser);
          break;
 
        case RID_TRY:
-         std_attrs = process_stmt_hotness_attribute (std_attrs);
+         std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
          statement = cp_parser_try_block (parser);
          break;
 
@@ -11158,11 +11175,11 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
        case RID_SYNCHRONIZED:
        case RID_ATOMIC_NOEXCEPT:
        case RID_ATOMIC_CANCEL:
-         std_attrs = process_stmt_hotness_attribute (std_attrs);
+         std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
          statement = cp_parser_transaction (parser, token);
          break;
        case RID_TRANSACTION_CANCEL:
-         std_attrs = process_stmt_hotness_attribute (std_attrs);
+         std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
          statement = cp_parser_transaction_cancel (parser);
          break;
 
@@ -11239,7 +11256,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
       if (loc_after_labels != NULL)
        *loc_after_labels = statement_location;
 
-      std_attrs = process_stmt_hotness_attribute (std_attrs);
+      std_attrs = process_stmt_hotness_attribute (std_attrs, attrs_loc);
 
       /* Look for an expression-statement instead.  */
       statement = cp_parser_expression_statement (parser, in_statement_expr);
@@ -11269,7 +11286,7 @@ cp_parser_statement (cp_parser* parser, tree in_statement_expr,
 
   /* Allow "[[fallthrough]];", but warn otherwise.  */
   if (std_attrs != NULL_TREE)
-    warning_at (attrs_location,
+    warning_at (attrs_loc,
                OPT_Wattributes,
                "attributes at the beginning of statement are ignored");
 }
@@ -11698,7 +11715,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
            cp_token *tok = cp_lexer_consume_token (parser->lexer);
            if (cxx_dialect < cxx17 && !in_system_header_at (tok->location))
              pedwarn (tok->location, 0, "%<if constexpr%> only available "
-                      "with -std=c++17 or -std=gnu++17");
+                      "with %<-std=c++17%> or %<-std=gnu++17%>");
          }
 
        /* Look for the `('.  */
@@ -11725,7 +11742,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
            if (cxx_dialect < cxx17)
              pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0,
                       "init-statement in selection statements only available "
-                      "with -std=c++17 or -std=gnu++17");
+                      "with %<-std=c++17%> or %<-std=gnu++17%>");
            cp_parser_init_statement (parser, &decl);
          }
 
@@ -12712,7 +12729,7 @@ cp_parser_init_statement (cp_parser *parser, tree *decl)
            {
              pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0,
                       "range-based %<for%> loops with initializer only "
-                      "available with -std=c++2a or -std=gnu++2a");
+                      "available with %<-std=c++2a%> or %<-std=gnu++2a%>");
              *decl = error_mark_node;
            }
        }
@@ -12736,7 +12753,7 @@ cp_parser_init_statement (cp_parser *parser, tree *decl)
          if (cxx_dialect < cxx11)
            pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0,
                     "range-based %<for%> loops only available with "
-                    "-std=c++11 or -std=gnu++11");
+                    "%<-std=c++11%> or %<-std=gnu++11%>");
        }
       else
        /* The ';' is not consumed yet because we told
@@ -13678,7 +13695,7 @@ cp_parser_decomposition_declaration (cp_parser *parser,
 
   if (cxx_dialect < cxx17)
     pedwarn (loc, 0, "structured bindings only available with "
-                    "-std=c++17 or -std=gnu++17");
+                    "%<-std=c++17%> or %<-std=gnu++17%>");
 
   tree pushed_scope;
   cp_declarator *declarator = make_declarator (cdk_decomp);
@@ -14215,8 +14232,8 @@ cp_parser_function_specifier_opt (cp_parser* parser,
 
            if (cxx_dialect < cxx2a)
              pedwarn (token->location, 0,
-                      "%<explicit(bool)%> only available with -std=c++2a "
-                      "or -std=gnu++2a");
+                      "%<explicit(bool)%> only available with %<-std=c++2a%> "
+                      "or %<-std=gnu++2a%>");
 
            /* Parse the constant-expression.  */
            expr = cp_parser_constant_expression (parser);
@@ -14384,7 +14401,7 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
       if (cxx_dialect < cxx17)
        pedwarn (input_location, OPT_Wpedantic,
                 "static_assert without a message "
-                "only available with -std=c++17 or -std=gnu++17");
+                "only available with %<-std=c++17%> or %<-std=gnu++17%>");
       /* Eat the ')'  */
       cp_lexer_consume_token (parser->lexer);
       message = build_string (1, "");
@@ -17626,17 +17643,17 @@ cp_parser_simple_type_specifier (cp_parser* parser,
                error_at (token->location,
                         "use of %<auto%> in lambda parameter declaration "
                         "only available with "
-                        "-std=c++14 or -std=gnu++14");
+                        "%<-std=c++14%> or %<-std=gnu++14%>");
            }
          else if (cxx_dialect < cxx14)
            error_at (token->location,
                     "use of %<auto%> in parameter declaration "
                     "only available with "
-                    "-std=c++14 or -std=gnu++14");
+                    "%<-std=c++14%> or %<-std=gnu++14%>");
          else if (!flag_concepts)
            pedwarn (token->location, 0,
                     "use of %<auto%> in parameter declaration "
-                    "only available with -fconcepts");
+                    "only available with %<-fconcepts%>");
        }
       else
        type = make_auto ();
@@ -19162,7 +19179,7 @@ cp_parser_namespace_definition (cp_parser* parser)
          if (cxx_dialect < cxx2a)
            pedwarn (cp_lexer_peek_token (parser->lexer)->location,
                     OPT_Wpedantic, "nested inline namespace definitions only "
-                    "available with -std=c++2a or -std=gnu++2a");
+                    "available with %<-std=c++2a%> or %<-std=gnu++2a%>");
          cp_lexer_consume_token (parser->lexer);
        }
 
@@ -19191,8 +19208,8 @@ cp_parser_namespace_definition (cp_parser* parser)
   
       if (!nested_definition_count && cxx_dialect < cxx17)
         pedwarn (input_location, OPT_Wpedantic,
-                 "nested namespace definitions only available with "
-                 "-std=c++17 or -std=gnu++17");
+                "nested namespace definitions only available with "
+                "%<-std=c++17%> or %<-std=gnu++17%>");
 
       /* Nested namespace names can create new namespaces (unlike
         other qualified-ids).  */
@@ -19396,7 +19413,8 @@ cp_parser_using_declaration (cp_parser* parser,
                                                  /*is_declaration=*/true);
   if (!qscope)
     qscope = global_namespace;
-  else if (UNSCOPED_ENUM_P (qscope))
+  else if (UNSCOPED_ENUM_P (qscope)
+          && !TYPE_FUNCTION_SCOPE_P (qscope))
     qscope = CP_TYPE_CONTEXT (qscope);
 
   if (access_declaration_p && cp_parser_error_occurred (parser))
@@ -19427,7 +19445,7 @@ cp_parser_using_declaration (cp_parser* parser,
          && !in_system_header_at (ell->location))
        pedwarn (ell->location, 0,
                 "pack expansion in using-declaration only available "
-                "with -std=c++17 or -std=gnu++17");
+                "with %<-std=c++17%> or %<-std=gnu++17%>");
       qscope = make_pack_expansion (qscope);
     }
 
@@ -19489,7 +19507,7 @@ cp_parser_using_declaration (cp_parser* parser,
       if (cxx_dialect < cxx17)
        pedwarn (comma->location, 0,
                 "comma-separated list in using-declaration only available "
-                "with -std=c++17 or -std=gnu++17");
+                "with %<-std=c++17%> or %<-std=gnu++17%>");
       goto again;
     }
 
@@ -19749,8 +19767,9 @@ cp_parser_asm_definition (cp_parser* parser)
   location_t volatile_loc = UNKNOWN_LOCATION;
   location_t inline_loc = UNKNOWN_LOCATION;
   location_t goto_loc = UNKNOWN_LOCATION;
+  location_t first_loc = UNKNOWN_LOCATION;
 
-  if (cp_parser_allow_gnu_extensions_p (parser) && parser->in_function_body)
+  if (cp_parser_allow_gnu_extensions_p (parser))
     for (;;)
       {
        cp_token *token = cp_lexer_peek_token (parser->lexer);
@@ -19764,7 +19783,12 @@ cp_parser_asm_definition (cp_parser* parser)
                inform (volatile_loc, "first seen here");
              }
            else
-             volatile_loc = loc;
+             {
+               if (!parser->in_function_body)
+                 warning_at (loc, 0, "asm qualifier %qT ignored outside of "
+                                     "function body", token->u.value);
+               volatile_loc = loc;
+             }
            cp_lexer_consume_token (parser->lexer);
            continue;
 
@@ -19776,6 +19800,8 @@ cp_parser_asm_definition (cp_parser* parser)
              }
            else
              inline_loc = loc;
+           if (!first_loc)
+             first_loc = loc;
            cp_lexer_consume_token (parser->lexer);
            continue;
 
@@ -19787,6 +19813,8 @@ cp_parser_asm_definition (cp_parser* parser)
              }
            else
              goto_loc = loc;
+           if (!first_loc)
+             first_loc = loc;
            cp_lexer_consume_token (parser->lexer);
            continue;
 
@@ -19806,6 +19834,12 @@ cp_parser_asm_definition (cp_parser* parser)
   bool inline_p = (inline_loc != UNKNOWN_LOCATION);
   bool goto_p = (goto_loc != UNKNOWN_LOCATION);
 
+  if (!parser->in_function_body && (inline_p || goto_p))
+    {
+      error_at (first_loc, "asm qualifier outside of function body");
+      inline_p = goto_p = false;
+    }
+
   /* Look for the opening `('.  */
   if (!cp_parser_require (parser, CPP_OPEN_PAREN, RT_OPEN_PAREN))
     return;
@@ -22573,11 +22607,25 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser,
                                                  bool in_function_try_block)
 {
   tree body, list;
-  const bool check_body_p =
-     DECL_CONSTRUCTOR_P (current_function_decl)
-     && DECL_DECLARED_CONSTEXPR_P (current_function_decl);
+  const bool check_body_p
+     = (DECL_CONSTRUCTOR_P (current_function_decl)
+       && DECL_DECLARED_CONSTEXPR_P (current_function_decl));
   tree last = NULL;
 
+  if (in_function_try_block
+      && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
+      && cxx_dialect < cxx2a)
+    {
+      if (DECL_CONSTRUCTOR_P (current_function_decl))
+       pedwarn (input_location, 0,
+                "function-try-block body of %<constexpr%> constructor only "
+                "available with %<-std=c++2a%> or %<-std=gnu++2a%>");
+      else
+       pedwarn (input_location, 0,
+                "function-try-block body of %<constexpr%> function only "
+                "available with %<-std=c++2a%> or %<-std=gnu++2a%>");
+    }
+
   /* Begin the function body.  */
   body = begin_function_body ();
   /* Parse the optional ctor-initializer.  */
@@ -22737,9 +22785,11 @@ cp_parser_braced_list (cp_parser* parser, bool* non_constant_p)
   /* If it's not a `}', then there is a non-trivial initializer.  */
   if (cp_lexer_next_token_is_not (parser->lexer, CPP_CLOSE_BRACE))
     {
+      bool designated;
       /* Parse the initializer list.  */
       CONSTRUCTOR_ELTS (initializer)
-       = cp_parser_initializer_list (parser, non_constant_p);
+       = cp_parser_initializer_list (parser, non_constant_p, &designated);
+      CONSTRUCTOR_IS_DESIGNATED_INIT (initializer) = designated;
       /* A trailing `,' token is allowed.  */
       if (cp_lexer_next_token_is (parser->lexer, CPP_COMMA))
        cp_lexer_consume_token (parser->lexer);
@@ -22859,10 +22909,12 @@ cp_parser_array_designator_p (cp_parser *parser)
    Returns a vec of constructor_elt.  The VALUE of each elt is an expression
    for the initializer.  If the INDEX of the elt is non-NULL, it is the
    IDENTIFIER_NODE naming the field to initialize.  NON_CONSTANT_P is
-   as for cp_parser_initializer.  */
+   as for cp_parser_initializer.  Set *DESIGNATED to a boolean whether there
+   are any designators.  */
 
 static vec<constructor_elt, va_gc> *
-cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
+cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p,
+                           bool *designated)
 {
   vec<constructor_elt, va_gc> *v = NULL;
   bool first_p = true;
@@ -22892,7 +22944,7 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
          if (cxx_dialect < cxx2a)
            pedwarn (loc, OPT_Wpedantic,
                     "C++ designated initializers only available with "
-                    "-std=c++2a or -std=gnu++2a");
+                    "%<-std=c++2a%> or %<-std=gnu++2a%>");
          /* Consume the `.'.  */
          cp_lexer_consume_token (parser->lexer);
          /* Consume the identifier.  */
@@ -23039,6 +23091,7 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p)
          IDENTIFIER_MARKED (designator) = 0;
     }
 
+  *designated = first_designator != NULL_TREE;
   return v;
 }
 
@@ -23167,7 +23220,9 @@ cp_parser_class_name (cp_parser *parser,
   decl = cp_parser_maybe_treat_template_as_class (decl, class_head_p);
 
   /* If this is a typename, create a TYPENAME_TYPE.  */
-  if (typename_p && decl != error_mark_node)
+  if (typename_p
+      && decl != error_mark_node
+      && !is_overloaded_fn (decl))
     {
       decl = make_typename_type (scope, decl, typename_type,
                                 /*complain=*/tf_error);
@@ -23983,8 +24038,11 @@ cp_parser_class_head (cp_parser* parser,
   cp_parser_check_class_key (class_key, type);
 
   /* If this type was already complete, and we see another definition,
-     that's an error.  */
-  if (type != error_mark_node && COMPLETE_TYPE_P (type))
+     that's an error.  Likewise if the type is already being defined:
+     this can happen, eg, when it's defined from within an expression 
+     (c++/84605).  */
+  if (type != error_mark_node
+      && (COMPLETE_TYPE_P (type) || TYPE_BEING_DEFINED (type)))
     {
       error_at (type_start_token->location, "redefinition of %q#T",
                type);
@@ -24103,7 +24161,7 @@ cp_parser_type_parameter_key (cp_parser* parser)
           by the standard until C++17.  */
        pedwarn (token->location, OPT_Wpedantic, 
                 "ISO C++ forbids typename key in template template parameter;"
-                " use -std=c++17 or -std=gnu++17");
+                " use %<-std=c++17%> or %<-std=gnu++17%>");
     }
   else
     cp_parser_error (parser, "expected %<class%> or %<typename%>");
@@ -24489,8 +24547,8 @@ cp_parser_member_declaration (cp_parser* parser)
                      && identifier != NULL_TREE)
                    pedwarn (loc, 0,
                             "default member initializers for bit-fields "
-                            "only available with -std=c++2a or "
-                            "-std=gnu++2a");
+                            "only available with %<-std=c++2a%> or "
+                            "%<-std=gnu++2a%>");
 
                  initializer = cp_parser_save_nsdmi (parser);
                  if (identifier == NULL_TREE)
@@ -25125,7 +25183,17 @@ cp_parser_noexcept_specification_opt (cp_parser* parser,
              parser->type_definition_forbidden_message
              = G_("types may not be defined in an exception-specification");
 
-             expr = cp_parser_constant_expression (parser);
+             bool non_constant_p;
+             expr
+               = cp_parser_constant_expression (parser,
+                                                /*allow_non_constant=*/true,
+                                                &non_constant_p);
+             if (non_constant_p
+                 && !require_potential_rvalue_constant_expression (expr))
+               {
+                 expr = NULL_TREE;
+                 return_cond = true;
+               }
 
              /* Restore the saved message.  */
              parser->type_definition_forbidden_message = saved_message;
@@ -25300,8 +25368,11 @@ cp_parser_try_block (cp_parser* parser)
 
   cp_parser_require_keyword (parser, RID_TRY, RT_TRY);
   if (parser->in_function_body
-      && DECL_DECLARED_CONSTEXPR_P (current_function_decl))
-    error ("%<try%> in %<constexpr%> function");
+      && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
+      && cxx_dialect < cxx2a)
+    pedwarn (input_location, 0,
+            "%<try%> in %<constexpr%> function only "
+            "available with %<-std=c++2a%> or %<-std=gnu++2a%>");
 
   try_block = begin_try_block ();
   cp_parser_compound_statement (parser, NULL, BCS_TRY_BLOCK, false);
@@ -25768,9 +25839,11 @@ cp_parser_gnu_attributes_opt (cp_parser* parser)
       cp_lexer_consume_token (parser->lexer);
       /* Look for the two `(' tokens.  */
       matching_parens outer_parens;
-      outer_parens.require_open (parser);
+      if (!outer_parens.require_open (parser))
+       ok = false;
       matching_parens inner_parens;
-      inner_parens.require_open (parser);
+      if (!inner_parens.require_open (parser))
+       ok = false;
 
       /* Peek at the next token.  */
       token = cp_lexer_peek_token (parser->lexer);
@@ -26178,7 +26251,7 @@ cp_parser_std_attribute_spec (cp_parser *parser)
                  && !in_system_header_at (input_location))
                pedwarn (input_location, 0,
                         "attribute using prefix only available "
-                        "with -std=c++17 or -std=gnu++17");
+                        "with %<-std=c++17%> or %<-std=gnu++17%>");
 
              cp_lexer_consume_token (parser->lexer);
              cp_lexer_consume_token (parser->lexer);
@@ -26501,7 +26574,7 @@ cp_parser_requires_clause_opt (cp_parser *parser)
          && tok->u.value == ridpointers[RID_REQUIRES])
        {
          error_at (cp_lexer_peek_token (parser->lexer)->location,
-                   "%<requires%> only available with -fconcepts");
+                   "%<requires%> only available with %<-fconcepts%>");
          /* Parse and discard the requires-clause.  */
          cp_lexer_consume_token (parser->lexer);
          cp_parser_requires_clause (parser);
@@ -27793,7 +27866,7 @@ cp_parser_template_declaration_after_parameters (cp_parser* parser,
          if (cxx_dialect > cxx17)
            error ("literal operator template %qD has invalid parameter list;"
                   "  Expected non-type template parameter pack <char...> "
-                  "  or single non-type parameter of class type",
+                  "or single non-type parameter of class type",
                   decl);
          else
            error ("literal operator template %qD has invalid parameter list."
@@ -32585,13 +32658,14 @@ cp_parser_oacc_data_clause_deviceptr (cp_parser *parser, tree list)
    seq */
 
 static tree
-cp_parser_oacc_simple_clause (cp_parser * /* parser  */,
-                             enum omp_clause_code code,
-                             tree list, location_t location)
+cp_parser_oacc_simple_clause (location_t loc, enum omp_clause_code code,
+                             tree list)
 {
-  check_no_duplicate_clause (list, code, omp_clause_code_name[code], location);
-  tree c = build_omp_clause (location, code);
+  check_no_duplicate_clause (list, code, omp_clause_code_name[code], loc);
+
+  tree c = build_omp_clause (loc, code);
   OMP_CLAUSE_CHAIN (c) = list;
+
   return c;
 }
 
@@ -32647,13 +32721,13 @@ cp_parser_oacc_single_int_clause (cp_parser *parser, omp_clause_code code,
 */
 
 static tree
-cp_parser_oacc_shape_clause (cp_parser *parser, omp_clause_code kind,
+cp_parser_oacc_shape_clause (cp_parser *parser, location_t loc,
+                            omp_clause_code kind,
                             const char *str, tree list)
 {
   const char *id = "num";
   cp_lexer *lexer = parser->lexer;
   tree ops[2] = { NULL_TREE, NULL_TREE }, c;
-  location_t loc = cp_lexer_peek_token (lexer)->location;
 
   if (kind == OMP_CLAUSE_VECTOR)
     id = "length";
@@ -32857,17 +32931,23 @@ cp_parser_oacc_wait_list (cp_parser *parser, location_t clause_loc, tree list)
 }
 
 /* OpenACC:
-   wait ( int-expr-list ) */
+   wait [( int-expr-list )] */
 
 static tree
 cp_parser_oacc_clause_wait (cp_parser *parser, tree list)
 {
   location_t location = cp_lexer_peek_token (parser->lexer)->location;
 
-  if (cp_lexer_peek_token (parser->lexer)->type != CPP_OPEN_PAREN)
-    return list;
+  if (cp_lexer_peek_token (parser->lexer)->type == CPP_OPEN_PAREN)
+    list = cp_parser_oacc_wait_list (parser, location, list);
+  else
+    {
+      tree c = build_omp_clause (location, OMP_CLAUSE_WAIT);
 
-  list = cp_parser_oacc_wait_list (parser, location, list);
+      OMP_CLAUSE_DECL (c) = build_int_cst (integer_type_node, GOMP_ASYNC_NOVAL);
+      OMP_CLAUSE_CHAIN (c) = list;
+      list = c;
+    }
 
   return list;
 }
@@ -34868,8 +34948,8 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
          c_name = "async";
          break;
        case PRAGMA_OACC_CLAUSE_AUTO:
-         clauses = cp_parser_oacc_simple_clause (parser, OMP_CLAUSE_AUTO,
-                                                clauses, here);
+         clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_AUTO,
+                                                 clauses);
          c_name = "auto";
          break;
        case PRAGMA_OACC_CLAUSE_COLLAPSE:
@@ -34913,8 +34993,8 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
          c_name = "device_resident";
          break;
        case PRAGMA_OACC_CLAUSE_FINALIZE:
-         clauses = cp_parser_oacc_simple_clause (parser, OMP_CLAUSE_FINALIZE,
-                                                 clauses, here);
+         clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_FINALIZE,
+                                                 clauses);
          c_name = "finalize";
          break;
        case PRAGMA_OACC_CLAUSE_FIRSTPRIVATE:
@@ -34924,7 +35004,7 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
          break;
        case PRAGMA_OACC_CLAUSE_GANG:
          c_name = "gang";
-         clauses = cp_parser_oacc_shape_clause (parser, OMP_CLAUSE_GANG,
+         clauses = cp_parser_oacc_shape_clause (parser, here, OMP_CLAUSE_GANG,
                                                 c_name, clauses);
          break;
        case PRAGMA_OACC_CLAUSE_HOST:
@@ -34936,15 +35016,13 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
          c_name = "if";
          break;
        case PRAGMA_OACC_CLAUSE_IF_PRESENT:
-         clauses = cp_parser_oacc_simple_clause (parser,
-                                                 OMP_CLAUSE_IF_PRESENT,
-                                                 clauses, here);
+         clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_IF_PRESENT,
+                                                 clauses);
          c_name = "if_present";
          break;
        case PRAGMA_OACC_CLAUSE_INDEPENDENT:
-         clauses = cp_parser_oacc_simple_clause (parser,
-                                                 OMP_CLAUSE_INDEPENDENT,
-                                                 clauses, here);
+         clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_INDEPENDENT,
+                                                 clauses);
          c_name = "independent";
          break;
        case PRAGMA_OACC_CLAUSE_LINK:
@@ -34979,8 +35057,8 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
          c_name = "reduction";
          break;
        case PRAGMA_OACC_CLAUSE_SEQ:
-         clauses = cp_parser_oacc_simple_clause (parser, OMP_CLAUSE_SEQ,
-                                                clauses, here);
+         clauses = cp_parser_oacc_simple_clause (here, OMP_CLAUSE_SEQ,
+                                                 clauses);
          c_name = "seq";
          break;
        case PRAGMA_OACC_CLAUSE_TILE:
@@ -34994,7 +35072,8 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
          break;
        case PRAGMA_OACC_CLAUSE_VECTOR:
          c_name = "vector";
-         clauses = cp_parser_oacc_shape_clause (parser, OMP_CLAUSE_VECTOR,
+         clauses = cp_parser_oacc_shape_clause (parser, here,
+                                                OMP_CLAUSE_VECTOR,
                                                 c_name, clauses);
          break;
        case PRAGMA_OACC_CLAUSE_VECTOR_LENGTH:
@@ -35009,7 +35088,8 @@ cp_parser_oacc_all_clauses (cp_parser *parser, omp_clause_mask mask,
          break;
        case PRAGMA_OACC_CLAUSE_WORKER:
          c_name = "worker";
-         clauses = cp_parser_oacc_shape_clause (parser, OMP_CLAUSE_WORKER,
+         clauses = cp_parser_oacc_shape_clause (parser, here,
+                                                OMP_CLAUSE_WORKER,
                                                 c_name, clauses);
          break;
        default: