On 19/05/21 16:05 -0400, Jason Merrill wrote:
On 5/19/21 3:55 PM, Jonathan Wakely wrote:
On 19/05/21 13:26 -0400, Jason Merrill wrote:
On 5/19/21 12:46 PM, Jonathan Wakely wrote:
On 19/05/21 17:39 +0100, Jonathan Wakely wrote:
Jakub pointed out I'd forgotten the spaces before the opening parens
for function calls. The attached patch should fix all those, with no
other changes.
Tested x86_64-linux. OK for trunk?
Jakub also pointed out we already have some similar diagnostics for
C++23, but I missed them as they say "only optional with" not "only
available with".
I'm testing the incremental change in the attached patch which also
adds -Wc++23-extensions, and I'll resend the full patch after that
finishes.
if (omitted_parms_loc && lambda_specs.any_specifiers_p)
{
- pedwarn (omitted_parms_loc, 0,
+ pedwarn (omitted_parms_loc, OPT_Wc__23_extensions,
You probably want to change
else if (cxx_dialect < cxx23)
omitted_parms_loc = cp_lexer_peek_token (parser->lexer)->location;
To use warn_about_dialect_p.
Ah yes.
And just above that there's another pedwarn about a C++14 feature
being used:
/* Default arguments shall not be specified in the
parameter-declaration-clause of a lambda-declarator. */
if (cxx_dialect < cxx14)
for (tree t = param_list; t; t = TREE_CHAIN (t))
if (TREE_PURPOSE (t) && DECL_P (TREE_VALUE (t)))
pedwarn (DECL_SOURCE_LOCATION (TREE_VALUE (t)), OPT_Wpedantic,
"default argument specified for lambda parameter");
I didn't notice that one initially. That should also use
warn_about_dialect_p and OPT_Wc__14_extensions.
Indeed.
Should I change the message to say "init capture" rather than
"default argument"?
No, this is about e.g. [](int = 42){}
OK, this is a simpler version of the patch, with docs now, but without
the new warn_about_cxx_dialect_p function (which isn't needed) and
with no changes to any actual warning text (I'll do that separately,
if at all).
I also caught a few more pedwarn cases that I missed previously.
Tested powerpc64le-linux. OK for trunk?
commit 01daea63635cff592f3fdbe7be2b704843b9193c
Author: Jonathan Wakely <jwak...@redhat.com>
Date: Wed May 19 21:35:58 2021
c++: Add new warning options for C++ language mismatches
This adds new warning flags, enabled by default: -Wc++11-extensions,
-Wc++14-extensions, -Wc++17-extensions, -Wc++20-extensions, and
-Wc++23-extensions. The names of the flags are copied from Clang, which
already has similar options.
No new diagnostics are added, but the new OPT_Wxxx variables are used to
control existing pedwarns about occurences of new C++ constructs in code
using an old C++ standard dialect. This allows several existing warnings
that cannot currently be disabled to be controlled by the appropriate
-Wno-xxx flag. For example, it will now be possible to disable warnings
about using variadic templates in C++98 code, by using the new
-Wno-c++11-extensions option. This will allow libstdc++ headers to
disable those warnings unconditionally by using diagnostic pragmas, so
that they are not emitted even if -Wsystem-headers is used.
Some of the affected diagnostics are currently only given when
-Wpedantic is used. Now that we have a more specific warning flag, we
could consider making them not depend on -Wpedantic, and only on the new
flag. This patch does not do that, as it intends to make no changes to
what is accepted/rejected by default. The only effect should be that
the new option is shown when -fdiagnostics-show-option is active, and
that some warnings can be disabled by using the new flags (and for the
warnings that previously only dependend on -Wpedantic, it will now be
possible to disable just those warnings while still using -Wpedantic for
its other benefits).
gcc/c-family/ChangeLog:
* c.opt (Wc++11-extensions, Wc++14-extensions)
(Wc++17-extensions, Wc++20-extensions, Wc++23-extensions): New
options.
gcc/cp/ChangeLog:
* call.c (maybe_warn_array_conv): Use new warning option.
* decl.c (mark_inline_variable, grokdeclarator): Likewise.
* error.c (maybe_warn_cpp0x): Likewise.
* parser.c (cp_parser_primary_expression)
(cp_parser_unqualified_id)
(cp_parser_pseudo_destructor_name)
(cp_parser_lambda_introducer)
(cp_parser_lambda_declarator_opt)
(cp_parser_selection_statement)
(cp_parser_init_statement)
(cp_parser_decomposition_declaration)
(cp_parser_function_specifier_opt)
(cp_parser_static_assert)
(cp_parser_namespace_definition)
(cp_parser_using_declaration)
(cp_parser_asm_definition)
(cp_parser_ctor_initializer_opt_and_function_body)
(cp_parser_initializer_list)
(cp_parser_type_parameter_key)
(cp_parser_member_declaration)
(cp_parser_try_block)
(cp_parser_std_attribute_spec): Likewise.
* pt.c (check_template_variable): Likewise.
gcc/ChangeLog:
* doc/invoke.texi (-Wno-c++11-extensions)
(-Wno-c++14-extensions, -Wno-c++17-extensions)
(-Wno-c++20-extensions, -Wno-c++23-extensions): Document
new options.
diff --git a/gcc/c-family/c.opt b/gcc/c-family/c.opt
index 5fcf961fd96..91929706aff 100644
--- a/gcc/c-family/c.opt
+++ b/gcc/c-family/c.opt
@@ -431,6 +431,26 @@ Wc++20-compat
C++ ObjC++ Var(warn_cxx20_compat) Warning LangEnabledBy(C++ ObjC++,Wall)
Warn about C++ constructs whose meaning differs between ISO C++ 2017 and ISO C++ 2020.
+Wc++11-extensions
+C++ ObjC++ Var(warn_cxx11_extensions) Warning LangEnabledBy(C++ ObjC++) Init(1)
+Warn about C++11 constructs in code compiled with an older standard.
+
+Wc++14-extensions
+C++ ObjC++ Var(warn_cxx14_extensions) Warning LangEnabledBy(C++ ObjC++) Init(1)
+Warn about C++14 constructs in code compiled with an older standard.
+
+Wc++17-extensions
+C++ ObjC++ Var(warn_cxx17_extensions) Warning LangEnabledBy(C++ ObjC++) Init(1)
+Warn about C++17 constructs in code compiled with an older standard.
+
+Wc++20-extensions
+C++ ObjC++ Var(warn_cxx20_extensions) Warning LangEnabledBy(C++ ObjC++) Init(1)
+Warn about C++20 constructs in code compiled with an older standard.
+
+Wc++23-extensions
+C++ ObjC++ Var(warn_cxx23_extensions) Warning LangEnabledBy(C++ ObjC++) Init(1)
+Warn about C++23 constructs in code compiled with an older standard.
+
Wcast-function-type
C ObjC C++ ObjC++ Var(warn_cast_function_type) Warning EnabledBy(Wextra)
Warn about casts between incompatible function types.
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 4a59b97c110..fa770f244cb 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -7469,8 +7469,9 @@ maybe_warn_array_conv (location_t loc, conversion *c, tree expr)
|| TYPE_DOMAIN (type) == NULL_TREE)
return;
- if (conv_binds_to_array_of_unknown_bound (c))
- pedwarn (loc, OPT_Wpedantic, "conversions to arrays of unknown bound "
+ if (pedantic && conv_binds_to_array_of_unknown_bound (c))
+ pedwarn (loc, OPT_Wc__20_extensions,
+ "conversions to arrays of unknown bound "
"are only available with %<-std=c++20%> or %<-std=gnu++20%>");
}
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 28052df9f45..7c32f09cf0e 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -11166,7 +11166,7 @@ mark_inline_variable (tree decl, location_t loc)
inlinep = false;
}
else if (cxx_dialect < cxx17)
- pedwarn (loc, 0, "inline variables are only available "
+ pedwarn (loc, OPT_Wc__17_extensions, "inline variables are only available "
"with %<-std=c++17%> or %<-std=gnu++17%>");
if (inlinep)
{
@@ -12002,13 +12002,13 @@ grokdeclarator (const cp_declarator *declarator,
storage_class = sc_none;
staticp = 0;
}
- if (constexpr_p && cxx_dialect < cxx20)
+ if (constexpr_p && pedantic && cxx_dialect < cxx20)
{
gcc_rich_location richloc (declspecs->locations[ds_virtual]);
richloc.add_range (declspecs->locations[ds_constexpr]);
- pedwarn (&richloc, OPT_Wpedantic, "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, "member %qD can be "
+ "declared both %<virtual%> and %<constexpr%> only in "
+ "%<-std=c++20%> or %<-std=gnu++20%>", dname);
}
}
friendp = decl_spec_seq_has_spec_p (declspecs, ds_friend);
@@ -12096,7 +12096,7 @@ grokdeclarator (const cp_declarator *declarator,
error_at (declspecs->locations[ds_consteval], "structured "
"binding declaration cannot be %qs", "consteval");
if (thread_p && cxx_dialect < cxx20)
- pedwarn (declspecs->locations[ds_thread], 0,
+ pedwarn (declspecs->locations[ds_thread], OPT_Wc__20_extensions,
"structured binding declaration can be %qs only in "
"%<-std=c++20%> or %<-std=gnu++20%>",
declspecs->gnu_thread_keyword_p
@@ -12118,7 +12118,7 @@ grokdeclarator (const cp_declarator *declarator,
break;
case sc_static:
if (cxx_dialect < cxx20)
- pedwarn (loc, 0,
+ pedwarn (loc, OPT_Wc__20_extensions,
"structured binding declaration can be %qs only in "
"%<-std=c++20%> or %<-std=gnu++20%>", "static");
break;
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 3c2276b1976..3d5eebd4bcd 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -4407,77 +4407,78 @@ maybe_warn_cpp0x (cpp0x_warn_str str)
switch (str)
{
case CPP0X_INITIALIZER_LISTS:
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__11_extensions,
"extended initializer lists "
"only available with %<-std=c++11%> or %<-std=gnu++11%>");
break;
case CPP0X_EXPLICIT_CONVERSION:
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__11_extensions,
"explicit conversion operators "
"only available with %<-std=c++11%> or %<-std=gnu++11%>");
break;
case CPP0X_VARIADIC_TEMPLATES:
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__11_extensions,
"variadic templates "
"only available with %<-std=c++11%> or %<-std=gnu++11%>");
break;
case CPP0X_LAMBDA_EXPR:
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__11_extensions,
"lambda expressions "
"only available with %<-std=c++11%> or %<-std=gnu++11%>");
break;
case CPP0X_AUTO:
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__11_extensions,
"C++11 auto only available with %<-std=c++11%> or "
"%<-std=gnu++11%>");
break;
case CPP0X_SCOPED_ENUMS:
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__11_extensions,
"scoped enums only available with %<-std=c++11%> or "
"%<-std=gnu++11%>");
break;
case CPP0X_DEFAULTED_DELETED:
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__11_extensions,
"defaulted and deleted functions "
"only available with %<-std=c++11%> or %<-std=gnu++11%>");
break;
case CPP0X_INLINE_NAMESPACES:
- pedwarn (input_location, OPT_Wpedantic,
- "inline namespaces "
- "only available with %<-std=c++11%> or %<-std=gnu++11%>");
+ if (pedantic)
+ pedwarn (input_location, OPT_Wc__11_extensions,
+ "inline namespaces "
+ "only available with %<-std=c++11%> or %<-std=gnu++11%>");
break;
case CPP0X_OVERRIDE_CONTROLS:
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__11_extensions,
"override controls (override/final) "
"only available with %<-std=c++11%> or %<-std=gnu++11%>");
break;
case CPP0X_NSDMI:
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__11_extensions,
"non-static data member initializers "
"only available with %<-std=c++11%> or %<-std=gnu++11%>");
break;
case CPP0X_USER_DEFINED_LITERALS:
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__11_extensions,
"user-defined literals "
"only available with %<-std=c++11%> or %<-std=gnu++11%>");
break;
case CPP0X_DELEGATING_CTORS:
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__11_extensions,
"delegating constructors "
"only available with %<-std=c++11%> or %<-std=gnu++11%>");
break;
case CPP0X_INHERITING_CTORS:
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__11_extensions,
"inheriting constructors "
"only available with %<-std=c++11%> or %<-std=gnu++11%>");
break;
case CPP0X_ATTRIBUTES:
- pedwarn (input_location, 0,
- "c++11 attributes "
+ pedwarn (input_location, OPT_Wc__11_extensions,
+ "C++11 attributes "
"only available with %<-std=c++11%> or %<-std=gnu++11%>");
break;
case CPP0X_REF_QUALIFIER:
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__11_extensions,
"ref-qualifiers "
"only available with %<-std=c++11%> or %<-std=gnu++11%>");
break;
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index bc0505df502..48b83d67b34 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -5577,8 +5577,9 @@ cp_parser_primary_expression (cp_parser *parser,
expr = cp_parser_fold_expression (parser, expr);
if (expr != error_mark_node
&& cxx_dialect < cxx17)
- pedwarn (input_location, 0, "fold-expressions only available "
- "with %<-std=c++17%> or %<-std=gnu++17%>");
+ pedwarn (input_location, OPT_Wc__17_extensions,
+ "fold-expressions only available with %<-std=c++17%> "
+ "or %<-std=gnu++17%>");
}
else
/* Let the front end know that this expression was
@@ -6325,7 +6326,7 @@ cp_parser_unqualified_id (cp_parser* parser,
if (cp_parser_is_keyword (token, RID_AUTO))
{
if (cxx_dialect < cxx14)
- pedwarn (loc, 0,
+ pedwarn (loc, OPT_Wc__14_extensions,
"%<~auto%> only available with "
"%<-std=c++14%> or %<-std=gnu++14%>");
cp_lexer_consume_token (parser->lexer);
@@ -8353,7 +8354,7 @@ cp_parser_pseudo_destructor_name (cp_parser* parser,
&& !type_dependent_expression_p (object))
{
if (cxx_dialect < cxx14)
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__14_extensions,
"%<~auto%> only available with "
"%<-std=c++14%> or %<-std=gnu++14%>");
cp_lexer_consume_token (parser->lexer);
@@ -11042,8 +11043,9 @@ 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%>");
+ pedwarn (loc, OPT_Wc__17_extensions,
+ "%<*this%> capture only available with "
+ "%<-std=c++17%> or %<-std=gnu++17%>");
cp_lexer_consume_token (parser->lexer);
cp_lexer_consume_token (parser->lexer);
if (LAMBDA_EXPR_THIS_CAPTURE (lambda_expr))
@@ -11081,7 +11083,8 @@ 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, 0, "pack init-capture only available with "
+ pedwarn (ellipsis_loc, OPT_Wc__20_extensions,
+ "pack init-capture only available with "
"%<-std=c++20%> or %<-std=gnu++20%>");
cp_lexer_consume_token (parser->lexer);
init_pack_expansion = true;
@@ -11122,7 +11125,7 @@ cp_parser_lambda_introducer (cp_parser* parser, tree lambda_expr)
bool direct, non_constant;
/* An explicit initializer exists. */
if (cxx_dialect < cxx14)
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__14_extensions,
"lambda capture initializers "
"only available with %<-std=c++14%> or %<-std=gnu++14%>");
capture_init_expr = cp_parser_initializer (parser, &direct,
@@ -11296,11 +11299,11 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
if (cp_lexer_next_token_is (parser->lexer, CPP_LESS))
{
if (cxx_dialect < cxx14)
- pedwarn (parser->lexer->next_token->location, 0,
+ pedwarn (parser->lexer->next_token->location, OPT_Wc__14_extensions,
"lambda templates are only available with "
"%<-std=c++14%> or %<-std=gnu++14%>");
- else if (cxx_dialect < cxx20)
- pedwarn (parser->lexer->next_token->location, OPT_Wpedantic,
+ 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%>");
@@ -11365,10 +11368,11 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
/* Default arguments shall not be specified in the
parameter-declaration-clause of a lambda-declarator. */
- if (cxx_dialect < cxx14)
+ if (pedantic && cxx_dialect < cxx14)
for (tree t = param_list; t; t = TREE_CHAIN (t))
if (TREE_PURPOSE (t) && DECL_P (TREE_VALUE (t)))
- pedwarn (DECL_SOURCE_LOCATION (TREE_VALUE (t)), OPT_Wpedantic,
+ pedwarn (DECL_SOURCE_LOCATION (TREE_VALUE (t)),
+ OPT_Wc__14_extensions,
"default argument specified for lambda parameter");
parens.require_close (parser);
@@ -11388,7 +11392,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
if (omitted_parms_loc && lambda_specs.any_specifiers_p)
{
- pedwarn (omitted_parms_loc, 0,
+ pedwarn (omitted_parms_loc, OPT_Wc__23_extensions,
"parameter declaration before lambda declaration "
"specifiers only optional with %<-std=c++2b%> or "
"%<-std=gnu++2b%>");
@@ -11407,7 +11411,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
tx_qual = cp_parser_tx_qualifier_opt (parser);
if (omitted_parms_loc && tx_qual)
{
- pedwarn (omitted_parms_loc, 0,
+ pedwarn (omitted_parms_loc, OPT_Wc__23_extensions,
"parameter declaration before lambda transaction "
"qualifier only optional with %<-std=c++2b%> or "
"%<-std=gnu++2b%>");
@@ -11420,7 +11424,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
if (omitted_parms_loc && exception_spec)
{
- pedwarn (omitted_parms_loc, 0,
+ pedwarn (omitted_parms_loc, OPT_Wc__23_extensions,
"parameter declaration before lambda exception "
"specification only optional with %<-std=c++2b%> or "
"%<-std=gnu++2b%>");
@@ -11438,7 +11442,7 @@ cp_parser_lambda_declarator_opt (cp_parser* parser, tree lambda_expr)
if (cp_lexer_next_token_is (parser->lexer, CPP_DEREF))
{
if (omitted_parms_loc)
- pedwarn (omitted_parms_loc, 0,
+ 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%>");
@@ -12301,8 +12305,9 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
cx = true;
cp_token *tok = cp_lexer_consume_token (parser->lexer);
if (cxx_dialect < cxx17)
- pedwarn (tok->location, 0, "%<if constexpr%> only available "
- "with %<-std=c++17%> or %<-std=gnu++17%>");
+ pedwarn (tok->location, OPT_Wc__17_extensions,
+ "%<if constexpr%> only available with "
+ "%<-std=c++17%> or %<-std=gnu++17%>");
}
/* Look for the `('. */
@@ -12327,7 +12332,8 @@ cp_parser_selection_statement (cp_parser* parser, bool *if_p,
{
tree decl;
if (cxx_dialect < cxx17)
- pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0,
+ 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%>");
if (cp_lexer_next_token_is_not (parser->lexer, CPP_SEMICOLON))
@@ -13398,7 +13404,8 @@ cp_parser_init_statement (cp_parser *parser, tree *decl)
if (cxx_dialect < cxx20)
{
- pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0,
+ 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%>");
*decl = error_mark_node;
@@ -13422,7 +13429,8 @@ cp_parser_init_statement (cp_parser *parser, tree *decl)
cp_lexer_consume_token (parser->lexer);
is_range_for = true;
if (cxx_dialect < cxx11)
- pedwarn (cp_lexer_peek_token (parser->lexer)->location, 0,
+ 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%>");
}
@@ -14665,8 +14673,9 @@ 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%>");
+ pedwarn (loc, OPT_Wc__17_extensions,
+ "structured bindings only available with "
+ "%<-std=c++17%> or %<-std=gnu++17%>");
tree pushed_scope;
cp_declarator *declarator = make_declarator (cdk_decomp);
@@ -15261,7 +15270,7 @@ cp_parser_function_specifier_opt (cp_parser* parser,
= G_("types may not be defined in explicit-specifier");
if (cxx_dialect < cxx20)
- pedwarn (token->location, 0,
+ pedwarn (token->location, OPT_Wc__20_extensions,
"%<explicit(bool)%> only available with %<-std=c++20%> "
"or %<-std=gnu++20%>");
@@ -15428,8 +15437,8 @@ cp_parser_static_assert(cp_parser *parser, bool member_p)
if (cp_lexer_peek_token (parser->lexer)->type == CPP_CLOSE_PAREN)
{
- if (cxx_dialect < cxx17)
- pedwarn (input_location, OPT_Wpedantic,
+ 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%>");
/* Eat the ')' */
@@ -20418,10 +20427,11 @@ cp_parser_namespace_definition (cp_parser* parser)
RID_INLINE);
if (nested_inline_p && nested_definition_count != 0)
{
- if (cxx_dialect < cxx20)
+ if (pedantic && cxx_dialect < cxx20)
pedwarn (cp_lexer_peek_token (parser->lexer)->location,
- OPT_Wpedantic, "nested inline namespace definitions only "
- "available with %<-std=c++20%> or %<-std=gnu++20%>");
+ OPT_Wc__20_extensions, "nested inline namespace "
+ "definitions only available with %<-std=c++20%> or "
+ "%<-std=gnu++20%>");
cp_lexer_consume_token (parser->lexer);
}
@@ -20448,8 +20458,8 @@ cp_parser_namespace_definition (cp_parser* parser)
break;
}
- if (!nested_definition_count && cxx_dialect < cxx17)
- pedwarn (input_location, OPT_Wpedantic,
+ 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%>");
@@ -20708,7 +20718,7 @@ cp_parser_using_declaration (cp_parser* parser,
{
cp_token *ell = cp_lexer_consume_token (parser->lexer);
if (cxx_dialect < cxx17)
- pedwarn (ell->location, 0,
+ pedwarn (ell->location, OPT_Wc__17_extensions,
"pack expansion in using-declaration only available "
"with %<-std=c++17%> or %<-std=gnu++17%>");
qscope = make_pack_expansion (qscope);
@@ -20741,7 +20751,7 @@ cp_parser_using_declaration (cp_parser* parser,
{
cp_token *comma = cp_lexer_consume_token (parser->lexer);
if (cxx_dialect < cxx17)
- pedwarn (comma->location, 0,
+ pedwarn (comma->location, OPT_Wc__17_extensions,
"comma-separated list in using-declaration only available "
"with %<-std=c++17%> or %<-std=gnu++17%>");
goto again;
@@ -21057,9 +21067,10 @@ cp_parser_asm_definition (cp_parser* parser)
functions. */
if (parser->in_function_body
&& DECL_DECLARED_CONSTEXPR_P (current_function_decl)
- && (cxx_dialect < cxx20))
- pedwarn (asm_loc, 0, "%<asm%> in %<constexpr%> function only available "
- "with %<-std=c++20%> or %<-std=gnu++20%>");
+ && cxx_dialect < cxx20)
+ pedwarn (asm_loc, OPT_Wc__20_extensions, "%<asm%> in %<constexpr%> "
+ "function only available with %<-std=c++20%> or "
+ "%<-std=gnu++20%>");
/* Handle the asm-qualifier-list. */
location_t volatile_loc = UNKNOWN_LOCATION;
@@ -24131,11 +24142,11 @@ cp_parser_ctor_initializer_opt_and_function_body (cp_parser *parser,
&& cxx_dialect < cxx20)
{
if (DECL_CONSTRUCTOR_P (current_function_decl))
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__20_extensions,
"function-try-block body of %<constexpr%> constructor only "
"available with %<-std=c++20%> or %<-std=gnu++20%>");
else
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__20_extensions,
"function-try-block body of %<constexpr%> function only "
"available with %<-std=c++20%> or %<-std=gnu++20%>");
}
@@ -24458,8 +24469,8 @@ cp_parser_initializer_list (cp_parser* parser, bool* non_constant_p,
|| (cp_lexer_peek_nth_token (parser->lexer, 3)->type
== CPP_OPEN_BRACE)))
{
- if (cxx_dialect < cxx20)
- pedwarn (loc, OPT_Wpedantic,
+ if (pedantic && cxx_dialect < cxx20)
+ pedwarn (loc, OPT_Wc__20_extensions,
"C++ designated initializers only available with "
"%<-std=c++20%> or %<-std=gnu++20%>");
/* Consume the `.'. */
@@ -25800,10 +25811,11 @@ cp_parser_type_parameter_key (cp_parser* parser)
if ((tag_type = cp_parser_token_is_type_parameter_key (token)) != none_type)
{
cp_lexer_consume_token (parser->lexer);
- if (pedantic && tag_type == typename_type && cxx_dialect < cxx17)
+ if (pedantic && tag_type == typename_type
+ && cxx_dialect < cxx17)
/* typename is not allowed in a template template parameter
by the standard until C++17. */
- pedwarn (token->location, OPT_Wpedantic,
+ pedwarn (token->location, OPT_Wc__17_extensions,
"ISO C++ forbids typename key in template template parameter;"
" use %<-std=c++17%> or %<-std=gnu++17%>");
}
@@ -26197,7 +26209,7 @@ cp_parser_member_declaration (cp_parser* parser)
= cp_lexer_peek_token (parser->lexer)->location;
if (cxx_dialect < cxx20
&& identifier != NULL_TREE)
- pedwarn (loc, 0,
+ pedwarn (loc, OPT_Wc__20_extensions,
"default member initializers for bit-fields "
"only available with %<-std=c++20%> or "
"%<-std=gnu++20%>");
@@ -27158,7 +27170,7 @@ cp_parser_try_block (cp_parser* parser)
if (parser->in_function_body
&& DECL_DECLARED_CONSTEXPR_P (current_function_decl)
&& cxx_dialect < cxx20)
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__20_extensions,
"%<try%> in %<constexpr%> function only "
"available with %<-std=c++20%> or %<-std=gnu++20%>");
@@ -28117,7 +28129,7 @@ cp_parser_std_attribute_spec (cp_parser *parser)
&& cp_lexer_nth_token_is (parser->lexer, 3, CPP_COLON))
{
if (cxx_dialect < cxx17)
- pedwarn (input_location, 0,
+ pedwarn (input_location, OPT_Wc__17_extensions,
"attribute using prefix only available "
"with %<-std=c++17%> or %<-std=gnu++17%>");
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index cbd2f3dc338..3d1787b6fc3 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -2703,7 +2703,7 @@ check_template_variable (tree decl)
&& PRIMARY_TEMPLATE_P (DECL_TI_TEMPLATE (decl)))
{
if (cxx_dialect < cxx14)
- pedwarn (DECL_SOURCE_LOCATION (decl), 0,
+ pedwarn (DECL_SOURCE_LOCATION (decl), OPT_Wc__14_extensions,
"variable templates only available with "
"%<-std=c++14%> or %<-std=gnu++14%>");
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 49c74f37497..9bcbcdc777c 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -330,7 +330,9 @@ Objective-C and Objective-C++ Dialects}.
-Wno-builtin-macro-redefined -Wc90-c99-compat -Wc99-c11-compat @gol
-Wc11-c2x-compat @gol
-Wc++-compat -Wc++11-compat -Wc++14-compat -Wc++17-compat @gol
--Wc++20-compat @gol
+-Wc++20-compat @gol
+-Wno-c++11-extensions -Wno-c++14-extensions -Wno-c++17-extensions @gol
+-Wno-c++20-extensions -Wno-c++23-extensions @gol
-Wcast-align -Wcast-align=strict -Wcast-function-type -Wcast-qual @gol
-Wchar-subscripts @gol
-Wclobbered -Wcomment @gol
@@ -8154,6 +8156,41 @@ and ISO C++ 2017. This warning is enabled by @option{-Wall}.
Warn about C++ constructs whose meaning differs between ISO C++ 2017
and ISO C++ 2020. This warning is enabled by @option{-Wall}.
+@item -Wno-c++11-extensions @r{(C++ and Objective-C++ only)}
+@opindex Wc++11-extensions
+@opindex Wno-c++11-extensions
+Do not warn about C++11 constructs in code being compiled using
+an older C++ standard. Even without this option, some C++11 constructs
+will only be diagnosed if @option{-Wpedantic} is used.
+
+@item -Wno-c++14-extensions @r{(C++ and Objective-C++ only)}
+@opindex Wc++14-extensions
+@opindex Wno-c++14-extensions
+Do not warn about C++14 constructs in code being compiled using
+an older C++ standard. Even without this option, some C++14 constructs
+will only be diagnosed if @option{-Wpedantic} is used.
+
+@item -Wno-c++17-extensions @r{(C++ and Objective-C++ only)}
+@opindex Wc++17-extensions
+@opindex Wno-c++17-extensions
+Do not warn about C++17 constructs in code being compiled using
+an older C++ standard. Even without this option, some C++17 constructs
+will only be diagnosed if @option{-Wpedantic} is used.
+
+@item -Wno-c++20-extensions @r{(C++ and Objective-C++ only)}
+@opindex Wc++20-extensions
+@opindex Wno-c++20-extensions
+Do not warn about C++20 constructs in code being compiled using
+an older C++ standard. Even without this option, some C++20 constructs
+will only be diagnosed if @option{-Wpedantic} is used.
+
+@item -Wno-c++23-extensions @r{(C++ and Objective-C++ only)}
+@opindex Wc++23-extensions
+@opindex Wno-c++23-extensions
+Do not warn about C++23 constructs in code being compiled using
+an older C++ standard. Even without this option, some C++23 constructs
+will only be diagnosed if @option{-Wpedantic} is used.
+
@item -Wcast-qual
@opindex Wcast-qual
@opindex Wno-cast-qual