On 19/05/21 23:52 +0100, Jonathan Wakely wrote:
On 19/05/21 16:08 -0400, Jason Merrill wrote:
On 5/19/21 4:05 PM, Jonathan Wakely wrote:
Oh, also we have https://gcc.gnu.org/bugzilla/show_bug.cgi?id=93769
which points out a problem with the current wording. Not a very
important one, but still ...

While I'm touching all 38(?) places that say "only available with
-std=c++NN or -std=gnu++NN I could change them to say something like
"only available since C++NN". Should I bother?

Clang's equivalent warnings say "are a C++11 feature" e.g.

ext.C:1:17: warning: inline namespaces are a C++11 feature [-Wc++11-inline-namespace]

(They have a specific warning for each feature, with
-Wc++11-extensions to control them all at once.)

The clang wording seems more accurate, as that PR points out.

OK, that requires touching a number of error_at and inform calls as
well as the pedwarns, so I'll address that separately in a later
patch.

Here's a WIP patch that rewords all those diagnostics. This doesn't
include the necessary testsuite changes, and I don't know when I'll
have time to do the rest of it. But it's a start. Does this look like
the right approach?



diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 7c32f09cf0e..b073883ad14 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -11166,8 +11166,8 @@ mark_inline_variable (tree decl, location_t loc)
       inlinep = false;
     }
   else if (cxx_dialect < cxx17)
-    pedwarn (loc, OPT_Wc__17_extensions, "inline variables are only available "
-	     "with %<-std=c++17%> or %<-std=gnu++17%>");
+    pedwarn (loc, OPT_Wc__17_extensions,
+	     "inline variables are a C++17 feature");
   if (inlinep)
     {
       retrofit_lang_decl (decl);
@@ -12006,9 +12006,9 @@ grokdeclarator (const cp_declarator *declarator,
 	{
 	  gcc_rich_location richloc (declspecs->locations[ds_virtual]);
 	  richloc.add_range (declspecs->locations[ds_constexpr]);
-	  pedwarn (&richloc, OPT_Wc__20_extensions, "member %qD can be "
-		   "declared both %<virtual%> and %<constexpr%> only in "
-		   "%<-std=c++20%> or %<-std=gnu++20%>", dname);
+	  pedwarn (&richloc, OPT_Wc__20_extensions, "declaring member %qD as "
+		   "both %<virtual%> and %<constexpr%> is a C++20 feature",
+		   dname);
 	}
     }
   friendp = decl_spec_seq_has_spec_p (declspecs, ds_friend);
@@ -12097,8 +12097,8 @@ grokdeclarator (const cp_declarator *declarator,
 		  "binding declaration cannot be %qs", "consteval");
       if (thread_p && cxx_dialect < cxx20)
 	pedwarn (declspecs->locations[ds_thread], OPT_Wc__20_extensions,
-		 "structured binding declaration can be %qs only in "
-		 "%<-std=c++20%> or %<-std=gnu++20%>",
+		 "structured binding declarations using %qs are a C++20 "
+		 "feature",
 		 declspecs->gnu_thread_keyword_p
 		 ? "__thread" : "thread_local");
       if (concept_p)
@@ -12119,8 +12119,9 @@ grokdeclarator (const cp_declarator *declarator,
 	case sc_static:
 	  if (cxx_dialect < cxx20)
 	    pedwarn (loc, OPT_Wc__20_extensions,
-		     "structured binding declaration can be %qs only in "
-		     "%<-std=c++20%> or %<-std=gnu++20%>", "static");
+		     "structured binding declarations using %qs are a C++20 "
+		     "feature",
+		     "static");
 	  break;
 	case sc_extern:
 	  error_at (loc, "structured binding declaration cannot be %qs",
@@ -12416,8 +12417,7 @@ grokdeclarator (const cp_declarator *declarator,
 				  "%<auto%> type specifier without "
 				  "trailing return type", name);
 			inform (typespec_loc,
-				"deduced return type only available "
-				"with %<-std=c++14%> or %<-std=gnu++14%>");
+				"deduced return type is a C++14 feature");
 		      }
 		    else if (virtualp)
 		      {
@@ -12489,8 +12489,7 @@ grokdeclarator (const cp_declarator *declarator,
 		  /* Not using maybe_warn_cpp0x because this should
 		     always be an error.  */
 		  error_at (typespec_loc,
-			    "trailing return type only available "
-			    "with %<-std=c++11%> or %<-std=gnu++11%>");
+			    "trailing return type is a C++11 feature");
 		else
 		  error_at (typespec_loc, "%qs function with trailing "
 			    "return type not declared with %<auto%> "
@@ -13584,8 +13583,7 @@ grokdeclarator (const cp_declarator *declarator,
 		if (constexpr_p && cxx_dialect < cxx20)
 		  {
 		    error_at (declspecs->locations[ds_constexpr],
-			      "%<constexpr%> destructors only available"
-			      " with %<-std=c++20%> or %<-std=gnu++20%>");
+			      "%<constexpr%> destructors are a C++20 feature");
 		    return error_mark_node;
 		  }
 		if (consteval_p)
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 3d5eebd4bcd..4c7cb1725c7 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -4408,79 +4408,64 @@ maybe_warn_cpp0x (cpp0x_warn_str str)
       {
       case CPP0X_INITIALIZER_LISTS:
 	pedwarn (input_location, OPT_Wc__11_extensions,
-		 "extended initializer lists "
-		 "only available with %<-std=c++11%> or %<-std=gnu++11%>");
+		 "extended initializer lists are a C++11 feature");
 	break;
       case CPP0X_EXPLICIT_CONVERSION:
 	pedwarn (input_location, OPT_Wc__11_extensions,
-		 "explicit conversion operators "
-		 "only available with %<-std=c++11%> or %<-std=gnu++11%>");
+		 "explicit conversion operators are a C++11 feature");
 	break;
       case CPP0X_VARIADIC_TEMPLATES:
 	pedwarn (input_location, OPT_Wc__11_extensions,
-		 "variadic templates "
-		 "only available with %<-std=c++11%> or %<-std=gnu++11%>");
+		 "variadic templates are a C++11 feature");
 	break;
       case CPP0X_LAMBDA_EXPR:
 	pedwarn (input_location, OPT_Wc__11_extensions,
-		 "lambda expressions "
-		  "only available with %<-std=c++11%> or %<-std=gnu++11%>");
+		 "lambda expressions are a C++11 feature");
 	break;
       case CPP0X_AUTO:
 	pedwarn (input_location, OPT_Wc__11_extensions,
-		 "C++11 auto only available with %<-std=c++11%> or "
-		 "%<-std=gnu++11%>");
+		 "deducing types with %<auto%> is a C++11 feature");
 	break;
       case CPP0X_SCOPED_ENUMS:
 	pedwarn (input_location, OPT_Wc__11_extensions,
-		 "scoped enums only available with %<-std=c++11%> or "
-		 "%<-std=gnu++11%>");
+		 "scoped enums are a C++11 feature");
 	break;
       case CPP0X_DEFAULTED_DELETED:
 	pedwarn (input_location, OPT_Wc__11_extensions,
-		 "defaulted and deleted functions "
-		 "only available with %<-std=c++11%> or %<-std=gnu++11%>");
+		 "defaulted and deleted functions are a C++11 feature");
 	break;
       case CPP0X_INLINE_NAMESPACES:
 	if (pedantic)
 	  pedwarn (input_location, OPT_Wc__11_extensions,
-		   "inline namespaces "
-		   "only available with %<-std=c++11%> or %<-std=gnu++11%>");
+		   "inline namespaces are a C++11 feature");
 	break;
       case CPP0X_OVERRIDE_CONTROLS:
 	pedwarn (input_location, OPT_Wc__11_extensions,
-		 "override controls (override/final) "
-		 "only available with %<-std=c++11%> or %<-std=gnu++11%>");
+		 "override controls (override/final) are a C++11 feature");
         break;
       case CPP0X_NSDMI:
 	pedwarn (input_location, OPT_Wc__11_extensions,
-		 "non-static data member initializers "
-		 "only available with %<-std=c++11%> or %<-std=gnu++11%>");
+		 "non-static data member initializers are a C++11 feature");
         break;
       case CPP0X_USER_DEFINED_LITERALS:
 	pedwarn (input_location, OPT_Wc__11_extensions,
-		 "user-defined literals "
-		 "only available with %<-std=c++11%> or %<-std=gnu++11%>");
+		 "user-defined literals are a C++11 feature");
 	break;
       case CPP0X_DELEGATING_CTORS:
 	pedwarn (input_location, OPT_Wc__11_extensions,
-		 "delegating constructors "
-		 "only available with %<-std=c++11%> or %<-std=gnu++11%>");
+		 "delegating constructors are a C++11 feature");
         break;
       case CPP0X_INHERITING_CTORS:
 	pedwarn (input_location, OPT_Wc__11_extensions,
-		 "inheriting constructors "
-		 "only available with %<-std=c++11%> or %<-std=gnu++11%>");
+		 "inheriting constructors are a C++11 feature");
         break;
       case CPP0X_ATTRIBUTES:
 	pedwarn (input_location, OPT_Wc__11_extensions,
-		 "C++11 attributes "
-		 "only available with %<-std=c++11%> or %<-std=gnu++11%>");
+		 "C++-style attributes are a C++11 feature");
 	break;
       case CPP0X_REF_QUALIFIER:
 	pedwarn (input_location, OPT_Wc__11_extensions,
-		 "ref-qualifiers "
-		 "only available with %<-std=c++11%> or %<-std=gnu++11%>");
+		 "ref-qualifiers are a C++11 feature");
 	break;
       default:
 	gcc_unreachable ();
diff --git a/gcc/cp/method.c b/gcc/cp/method.c
index dd745237f22..321869b13db 100644
--- a/gcc/cp/method.c
+++ b/gcc/cp/method.c
@@ -1165,8 +1165,7 @@ early_check_defaulted_comparison (tree fn)
 
   if (cxx_dialect < cxx20)
     {
-      error_at (loc, "defaulted %qD only available with %<-std=c++20%> or "
-		     "%<-std=gnu++20%>", fn);
+      error_at (loc, "defaulted %qD is a C++20 feature", fn);
       return false;
     }
 
diff --git a/gcc/cp/name-lookup.c b/gcc/cp/name-lookup.c
index a6c9e68a19e..d291cf0fb86 100644
--- a/gcc/cp/name-lookup.c
+++ b/gcc/cp/name-lookup.c
@@ -5626,8 +5626,7 @@ lookup_using_decl (tree scope, name_lookup &lookup)
     {
       /* Naming an enumeration member.  */
       if (cxx_dialect < cxx20)
-	error ("%<using%> with enumeration scope %q#T "
-	       "only available with %<-std=c++20%> or %<-std=gnu++20%>",
+	error ("%<using%> with enumeration scope %q#T is a C++20 feature",
 	       scope);
       lookup.value = lookup_enumerator (scope, lookup.name);
     }
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 48b83d67b34..8c8c5496866 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -3429,8 +3429,8 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id,
 		"invalid use of template-name %qE without an argument list",
 		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%>");
+	inform (location, "class template argument deduction is a C++17 "
+			  "feature");
       inform (DECL_SOURCE_LOCATION (decl), "%qD declared here", decl);
     }
   else if (TREE_CODE (id) == BIT_NOT_EXPR)
@@ -3463,11 +3463,9 @@ 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%>");
+	inform (location, "%<constexpr%> is a C++11 feature");
       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%>");
+	inform (location, "%<noexcept%> is a C++11 feature");
       else if (TREE_CODE (id) == IDENTIFIER_NODE
 	       && (id_equal (id, "module") || id_equal (id, "import")))
 	{
@@ -3484,17 +3482,15 @@ cp_parser_diagnose_invalid_type_name (cp_parser *parser, tree id,
       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%>");
+	inform (location, "%<thread_local%> is a C++11 feature");
       else if (cxx_dialect < cxx20 && id == ridpointers[(int)RID_CONSTINIT])
-	inform (location, "C++20 %<constinit%> only available with "
-		"%<-std=c++20%> or %<-std=gnu++20%>");
+	inform (location, "%<constinit%> is a C++20 feature");
       else if (!flag_concepts && id == ridpointers[(int)RID_CONCEPT])
-	inform (location, "%<concept%> only available with %<-std=c++20%> or "
-		"%<-fconcepts%>");
+	inform (location, "%<concept%> is a C++20 feature, or is available "
+		"with %<-fconcepts%>");
       else if (!flag_concepts && id == ridpointers[(int)RID_REQUIRES])
-	inform (location, "%<requires%> only available with %<-std=c++20%> or "
-		"%<-fconcepts%>");
+	inform (location, "%<requires%> is a C++20 feature, or is available "
+		"with %<-fconcepts%>");
       else if (processing_template_decl && current_class_type
 	       && TYPE_BINFO (current_class_type))
 	{
@@ -5578,8 +5574,7 @@ cp_parser_primary_expression (cp_parser *parser,
 	    if (expr != error_mark_node
 		&& cxx_dialect < cxx17)
 	      pedwarn (input_location, OPT_Wc__17_extensions,
-		       "fold-expressions only available with %<-std=c++17%> "
-		       "or %<-std=gnu++17%>");
+		       "fold-expressions are a C++17 feature");
 	  }
 	else
 	  /* Let the front end know that this expression was
@@ -6327,8 +6322,7 @@ cp_parser_unqualified_id (cp_parser* parser,
 	  {
 	    if (cxx_dialect < cxx14)
 	      pedwarn (loc, OPT_Wc__14_extensions,
-		       "%<~auto%> only available with "
-		       "%<-std=c++14%> or %<-std=gnu++14%>");
+		       "%<~auto%> is a C++14 feature");
 	    cp_lexer_consume_token (parser->lexer);
 	    return build_min_nt_loc (loc, BIT_NOT_EXPR, make_auto ());
 	  }
@@ -8355,8 +8349,7 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
     {
       if (cxx_dialect < cxx14)
 	pedwarn (input_location, OPT_Wc__14_extensions,
-		 "%<~auto%> only available with "
-		 "%<-std=c++14%> or %<-std=gnu++14%>");
+		 "%<~auto%> is a C++14 feature");
       cp_lexer_consume_token (parser->lexer);
       cp_lexer_consume_token (parser->lexer);
       *scope = NULL_TREE;
@@ -10824,8 +10817,8 @@ cp_parser_lambda_expression (cp_parser* parser)
       if (!token->error_reported)
 	{
 	  error_at (LAMBDA_EXPR_LOCATION (lambda_expr),
-		    "lambda-expression in unevaluated context"
-		    " only available with %<-std=c++20%> or %<-std=gnu++20%>");
+		    "lambda-expression in unevaluated context are a "
+		    "C++20 feature");
 	  token->error_reported = true;
 	}
       ok = false;
@@ -10835,7 +10828,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++20%> or %<-std=gnu++20%>");
+		    " is a C++20 feature");
 	  token->error_reported = true;
 	}
       ok = false;
@@ -11044,8 +11037,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, OPT_Wc__17_extensions,
-		     "%<*this%> capture only available with "
-		     "%<-std=c++17%> or %<-std=gnu++17%>");
+		     "%<*this%> capture is a C++17 feature");
 	  cp_lexer_consume_token (parser->lexer);
 	  cp_lexer_consume_token (parser->lexer);
 	  if (LAMBDA_EXPR_THIS_CAPTURE (lambda_expr))
@@ -11084,8 +11076,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
 	  ellipsis_loc = cp_lexer_peek_token (parser->lexer)->location;
 	  if (cxx_dialect < cxx20)
 	    pedwarn (ellipsis_loc, OPT_Wc__20_extensions,
-		     "pack init-capture only available with "
-		     "%<-std=c++20%> or %<-std=gnu++20%>");
+		     "pack init-capture is a C++20 feature");
 	  cp_lexer_consume_token (parser->lexer);
 	  init_pack_expansion = true;
 	}
@@ -11126,8 +11117,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
 	  /* An explicit initializer exists.  */
 	  if (cxx_dialect < cxx14)
 	    pedwarn (input_location, OPT_Wc__14_extensions,
-		     "lambda capture initializers "
-		     "only available with %<-std=c++14%> or %<-std=gnu++14%>");
+		     "lambda capture initializers are a C++14 feature");
 	  capture_init_expr = cp_parser_initializer (parser, &direct,
 						     &non_constant, true);
 	  explicit_init_p = true;
@@ -11300,12 +11290,10 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
     {
       if (cxx_dialect < cxx14)
 	pedwarn (parser->lexer->next_token->location, OPT_Wc__14_extensions,
-		 "lambda templates are only available with "
-		 "%<-std=c++14%> or %<-std=gnu++14%>");
+		 "lambda templates are a C++14 feature");
       else if (pedantic && cxx_dialect < cxx20)
 	pedwarn (parser->lexer->next_token->location, OPT_Wc__20_extensions,
-		 "lambda templates are only available with "
-		 "%<-std=c++20%> or %<-std=gnu++20%>");
+		 "lambda templates are a C++20 feature");
 
       cp_lexer_consume_token (parser->lexer);
 
@@ -11394,8 +11382,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
     {
       pedwarn (omitted_parms_loc, OPT_Wc__23_extensions,
 	       "parameter declaration before lambda declaration "
-	       "specifiers only optional with %<-std=c++2b%> or "
-	       "%<-std=gnu++2b%>");
+	       "specifiers only optional since C++23");
       omitted_parms_loc = UNKNOWN_LOCATION;
     }
 
@@ -11413,8 +11400,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
     {
       pedwarn (omitted_parms_loc, OPT_Wc__23_extensions,
 	       "parameter declaration before lambda transaction "
-	       "qualifier only optional with %<-std=c++2b%> or "
-	       "%<-std=gnu++2b%>");
+	       "qualifier only optional since C++23");
       omitted_parms_loc = UNKNOWN_LOCATION;
     }
 
@@ -11426,8 +11412,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
     {
       pedwarn (omitted_parms_loc, OPT_Wc__23_extensions,
 	       "parameter declaration before lambda exception "
-	       "specification only optional with %<-std=c++2b%> or "
-	       "%<-std=gnu++2b%>");
+	       "specification only optional since C++23");
       omitted_parms_loc = UNKNOWN_LOCATION;
     }
 
@@ -11444,8 +11429,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
       if (omitted_parms_loc)
 	pedwarn (omitted_parms_loc, OPT_Wc__23_extensions,
 		 "parameter declaration before lambda trailing "
-		 "return type only optional with %<-std=c++2b%> or "
-		 "%<-std=gnu++2b%>");
+		 "return type only optional since C++23%>");
       cp_lexer_consume_token (parser->lexer);
       return_type = cp_parser_trailing_type_id (parser);
     }
@@ -11486,8 +11470,7 @@ 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 is a C++17 feature");
       }
     if (lambda_specs.locations[ds_consteval])
       return_type_specs.locations[ds_consteval]
@@ -12306,8 +12289,7 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
 	    cp_token *tok = cp_lexer_consume_token (parser->lexer);
 	    if (cxx_dialect < cxx17)
 	      pedwarn (tok->location, OPT_Wc__17_extensions,
-		       "%<if constexpr%> only available with "
-		       "%<-std=c++17%> or %<-std=gnu++17%>");
+		       "%<if constexpr%> is a C++17 feature");
 	  }
 
 	/* Look for the `('.  */
@@ -12334,8 +12316,8 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
 	    if (cxx_dialect < cxx17)
 	      pedwarn (cp_lexer_peek_token (parser->lexer)->location,
 		       OPT_Wc__17_extensions,
-		       "init-statement in selection statements only available "
-		       "with %<-std=c++17%> or %<-std=gnu++17%>");
+		       "init-statement in selection statements is a C++17 "
+		       "feature");
 	    if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
 	      /* A non-empty init-statement can have arbitrary side
 		 effects.  */
@@ -13406,8 +13388,8 @@ cp_parser_init_statement (cp_parser *parser, tree *decl)
 	    {
 	      pedwarn (cp_lexer_peek_token (parser->lexer)->location,
 		       OPT_Wc__20_extensions,
-		       "range-based %<for%> loops with initializer only "
-		       "available with %<-std=c++20%> or %<-std=gnu++20%>");
+		       "range-based %<for%> loops with initializer are a "
+		       "C++20 feature")
 	      *decl = error_mark_node;
 	    }
 	}
@@ -13431,8 +13413,7 @@ cp_parser_init_statement (cp_parser *parser, tree *decl)
 	  if (cxx_dialect < cxx11)
 	    pedwarn (cp_lexer_peek_token (parser->lexer)->location,
 		     OPT_Wc__11_extensions,
-		     "range-based %<for%> loops only available with "
-		     "%<-std=c++11%> or %<-std=gnu++11%>");
+		     "range-based %<for%> loops are a C++11 feature");
 	}
       else
 	/* The ';' is not consumed yet because we told
@@ -14674,8 +14655,7 @@ cp_parser_decomposition_declaration (cp_parser *parser,
 
   if (cxx_dialect < cxx17)
     pedwarn (loc, OPT_Wc__17_extensions,
-	     "structured bindings only available with "
-	     "%<-std=c++17%> or %<-std=gnu++17%>");
+	     "structured bindings are a C++17 feature");
 
   tree pushed_scope;
   cp_declarator *declarator = make_declarator (cdk_decomp);
@@ -15271,8 +15251,7 @@ cp_parser_function_specifier_opt (cp_parser* parser,
 
 	    if (cxx_dialect < cxx20)
 	      pedwarn (token->location, OPT_Wc__20_extensions,
-		       "%<explicit(bool)%> only available with %<-std=c++20%> "
-		       "or %<-std=gnu++20%>");
+		       "%<explicit(bool)%> is a C++20 feature");
 
 	    /* Parse the constant-expression.  */
 	    expr = cp_parser_constant_expression (parser);
@@ -15439,8 +15418,7 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
     {
       if (pedantic && cxx_dialect < cxx17)
 	pedwarn (input_location, OPT_Wc__17_extensions,
-		 "%<static_assert%> without a message "
-		 "only available with %<-std=c++17%> or %<-std=gnu++17%>");
+		 "%<static_assert%> without a message is a C++17 feature");
       /* Eat the ')'  */
       cp_lexer_consume_token (parser->lexer);
       message = build_string (1, "");
@@ -15641,8 +15619,7 @@ cp_parser_decltype (cp_parser *parser)
       if (cxx_dialect < cxx14)
 	{
 	  error_at (start_token->location,
-		    "%<decltype(auto)%> type specifier only available with "
-		    "%<-std=c++14%> or %<-std=gnu++14%>");
+		    "%<decltype(auto)%> type specifier is a C++14 feature");
 	  expr = error_mark_node;
 	}
     }
@@ -18770,14 +18747,12 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 	      if (cxx_dialect < cxx14)
 		error_at (token->location,
 			 "use of %<auto%> in lambda parameter declaration "
-			 "only available with "
-			 "%<-std=c++14%> or %<-std=gnu++14%>");
+			 "is a C++14 feature");
 	    }
 	  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%>");
+		     "is a C++14 feature");
 	  else if (!flag_concepts)
 	    pedwarn (token->location, 0,
 		     "use of %<auto%> in parameter declaration "
@@ -20430,8 +20405,7 @@ cp_parser_namespace_definition (cp_parser* parser)
 	  if (pedantic && cxx_dialect < cxx20)
 	    pedwarn (cp_lexer_peek_token (parser->lexer)->location,
 		     OPT_Wc__20_extensions, "nested inline namespace "
-		     "definitions only available with %<-std=c++20%> or "
-		     "%<-std=gnu++20%>");
+		     "definitions are a C++20 feature");
 	  cp_lexer_consume_token (parser->lexer);
 	}
 
@@ -20460,8 +20434,7 @@ cp_parser_namespace_definition (cp_parser* parser)
 
       if (!nested_definition_count && pedantic && cxx_dialect < cxx17)
         pedwarn (input_location, OPT_Wc__17_extensions,
-		 "nested namespace definitions only available with "
-		 "%<-std=c++17%> or %<-std=gnu++17%>");
+		 "nested namespace definitions are a C++17 feature");
 
       /* Nested namespace names can create new namespaces (unlike
 	 other qualified-ids).  */
@@ -20719,8 +20692,7 @@ cp_parser_using_declaration (cp_parser* parser,
       cp_token *ell = cp_lexer_consume_token (parser->lexer);
       if (cxx_dialect < cxx17)
 	pedwarn (ell->location, OPT_Wc__17_extensions,
-		 "pack expansion in using-declaration only available "
-		 "with %<-std=c++17%> or %<-std=gnu++17%>");
+		 "pack expansion in using-declaration is a C++17 feature");
       qscope = make_pack_expansion (qscope);
     }
 
@@ -20752,8 +20724,8 @@ cp_parser_using_declaration (cp_parser* parser,
       cp_token *comma = cp_lexer_consume_token (parser->lexer);
       if (cxx_dialect < cxx17)
 	pedwarn (comma->location, OPT_Wc__17_extensions,
-		 "comma-separated list in using-declaration only available "
-		 "with %<-std=c++17%> or %<-std=gnu++17%>");
+		 "comma-separated list in using-declaration is a C++17 "
+		 "feature");
       goto again;
     }
 
@@ -20808,8 +20780,7 @@ cp_parser_using_enum (cp_parser *parser)
      shall have a reachable enum-specifier.  */
   const char *msg = nullptr;
   if (cxx_dialect < cxx20)
-    msg = _("%<using enum%> "
-	    "only available with %<-std=c++20%> or %<-std=gnu++20%>");
+    msg = _("%<using enum%> is a C++20 feature");
   else if (dependent_type_p (type))
     msg = _("%<using enum%> of dependent type %qT");
   else if (TREE_CODE (type) != ENUMERAL_TYPE)
@@ -21069,8 +21040,7 @@ cp_parser_asm_definition (cp_parser* parser)
       && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
       && cxx_dialect < cxx20)
     pedwarn (asm_loc, OPT_Wc__20_extensions, "%<asm%> in %<constexpr%> "
-	     "function only available with %<-std=c++20%> or "
-	     "%<-std=gnu++20%>");
+	     "function is a C++20 feature");
 
   /* Handle the asm-qualifier-list.  */
   location_t volatile_loc = UNKNOWN_LOCATION;
@@ -24143,12 +24113,12 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser,
     {
       if (DECL_CONSTRUCTOR_P (current_function_decl))
 	pedwarn (input_location, OPT_Wc__20_extensions,
-		 "function-try-block body of %<constexpr%> constructor only "
-		 "available with %<-std=c++20%> or %<-std=gnu++20%>");
+		 "function-try-block body of %<constexpr%> constructor "
+		 "is a C++20 feature");
       else
 	pedwarn (input_location, OPT_Wc__20_extensions,
-		 "function-try-block body of %<constexpr%> function only "
-		 "available with %<-std=c++20%> or %<-std=gnu++20%>");
+		 "function-try-block body of %<constexpr%> function "
+		 "is a C++20 feature");
     }
 
   /* Begin the function body.  */
@@ -24471,8 +24441,7 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p,
 	{
 	  if (pedantic && cxx_dialect < cxx20)
 	    pedwarn (loc, OPT_Wc__20_extensions,
-		     "C++ designated initializers only available with "
-		     "%<-std=c++20%> or %<-std=gnu++20%>");
+		     "C++ designated initializers are a C++20 feature");
 	  /* Consume the `.'.  */
 	  cp_lexer_consume_token (parser->lexer);
 	  /* Consume the identifier.  */
@@ -25816,8 +25785,8 @@ cp_parser_type_parameter_key (cp_parser* parser)
 	/* typename is not allowed in a template template parameter
 	   by the standard until C++17.  */
 	pedwarn (token->location, OPT_Wc__17_extensions,
-		 "ISO C++ forbids typename key in template template parameter;"
-		 " use %<-std=c++17%> or %<-std=gnu++17%>");
+		 "typename key in template template parameter is a C++17 "
+		 "feature");
     }
   else
     cp_parser_error (parser, "expected %<class%> or %<typename%>");
@@ -26211,8 +26180,7 @@ cp_parser_member_declaration (cp_parser* parser)
 		      && identifier != NULL_TREE)
 		    pedwarn (loc, OPT_Wc__20_extensions,
 			     "default member initializers for bit-fields "
-			     "only available with %<-std=c++20%> or "
-			     "%<-std=gnu++20%>");
+			     "are a C++20 feature");
 
 		  initializer = cp_parser_save_nsdmi (parser);
 		  if (identifier == NULL_TREE)
@@ -27171,8 +27139,7 @@ cp_parser_try_block (cp_parser* parser)
       && DECL_DECLARED_CONSTEXPR_P (current_function_decl)
       && cxx_dialect < cxx20)
     pedwarn (input_location, OPT_Wc__20_extensions,
-	     "%<try%> in %<constexpr%> function only "
-	     "available with %<-std=c++20%> or %<-std=gnu++20%>");
+	     "%<try%> in %<constexpr%> function is a C++20 feature");
 
   try_block = begin_try_block ();
   cp_parser_compound_statement (parser, NULL, BCS_TRY_BLOCK, false);
@@ -28130,8 +28097,7 @@ cp_parser_std_attribute_spec (cp_parser *parser)
 	    {
 	      if (cxx_dialect < cxx17)
 		pedwarn (input_location, OPT_Wc__17_extensions,
-			 "attribute using prefix only available "
-			 "with %<-std=c++17%> or %<-std=gnu++17%>");
+			 "attribute using prefix is a C++17 feature");
 
 	      cp_lexer_consume_token (parser->lexer);
 	      cp_lexer_consume_token (parser->lexer);
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 3d1787b6fc3..43a76a9aece 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -2704,8 +2704,7 @@ check_template_variable (tree decl)
     {
       if (cxx_dialect < cxx14)
         pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wc__14_extensions,
-		 "variable templates only available with "
-		 "%<-std=c++14%> or %<-std=gnu++14%>");
+		 "variable templates are a C++14 feature");
 
       // Namespace-scope variable templates should have a template header.
       ++wanted;
@@ -5583,8 +5582,8 @@ check_default_tmpl_args (tree decl, tree parms, bool is_primary,
     msg = G_("default template arguments may not be used in template "
 	     "friend declarations");
   else if (TREE_CODE (decl) == FUNCTION_DECL && (cxx_dialect == cxx98))
-    msg = G_("default template arguments may not be used in function templates "
-	     "without %<-std=c++11%> or %<-std=gnu++11%>");
+    msg = G_("default template arguments in function templates "
+	     "are a C++11 feature");
   else if (is_partial)
     msg = G_("default template arguments may not be used in "
 	     "partial specializations");
@@ -26546,8 +26545,8 @@ invalid_nontype_parm_type_p (tree type, tsubst_flags_t complain)
       if (CLASS_PLACEHOLDER_TEMPLATE (type) && cxx_dialect < cxx20)
 	{
 	  if (complain & tf_error)
-	    error ("non-type template parameters of deduced class type only "
-		   "available with %<-std=c++20%> or %<-std=gnu++20%>");
+	    error ("non-type template parameters of deduced class type "
+		   "are a C++20 feature");
 	  return true;
 	}
       return false;
@@ -26587,8 +26586,8 @@ invalid_nontype_parm_type_p (tree type, tsubst_flags_t complain)
   else if (CLASS_TYPE_P (type))
     {
       if (complain & tf_error)
-	error ("non-type template parameters of class type only available "
-	       "with %<-std=c++20%> or %<-std=gnu++20%>");
+	error ("non-type template parameters of class type are a C++20 "
+	       "feature");
       return true;
     }
 
@@ -29304,8 +29303,7 @@ do_class_deduction (tree ptype, tree tmpl, tree init,
   else if (cxx_dialect < cxx20 && DECL_ALIAS_TEMPLATE_P (tmpl))
     {
       if (complain & tf_error)
-	error ("alias template deduction only available "
-	       "with %<-std=c++20%> or %<-std=gnu++20%>");
+	error ("alias template deduction is a C++20 feature");
       return error_mark_node;
     }
 

Reply via email to