From: Jakub Jelinek Date: Wed, 30 Jul 2025 11:23:56 +0000 (+0200) Subject: c++: Make __extension__ silence -Wlong-long pedwarns/warnings [PR121133] X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=281a6a0a8b3b2fd7c07ad6e0bf8454d60d9d5034;p=thirdparty%2Fgcc.git c++: Make __extension__ silence -Wlong-long pedwarns/warnings [PR121133] The PR13358 r0-92909 change changed the diagnostics on long long in C++ (either with -std=c++98 or -Wlong-long), but unlike the C FE we unfortunately warn even in the __extension__ long long a; etc. cases. The C FE in that case in disable_extension_diagnostics saves and clears not just pedantic flag but also warn_long_long (and several others), while C++ FE only temporarily disables pedantic. The following patch makes it behave like the C FE in this regard, though (__extension__ 1LL) still doesn't work because of the separate lexing (and I must say I have no idea how to fix that). Or do you prefer a solution closer to the C FE, cp_parser_extension_opt saving the values into a bitfield and have another function to restore the state (or use RAII)? 2025-07-30 Jakub Jelinek PR c++/121133 * parser.cc (cp_parser_unary_expression): Adjust cp_parser_extension_opt caller and restore warn_long_long. (cp_parser_declaration): Likewise. (cp_parser_block_declaration): Likewise. (cp_parser_member_declaration): Likewise. (cp_parser_extension_opt): Add SAVED_LONG_LONG argument, save previous warn_long_long state into it and clear it for __extension__. * g++.dg/warn/pr121133-1.C: New test. * g++.dg/warn/pr121133-2.C: New test. * g++.dg/warn/pr121133-3.C: New test. * g++.dg/warn/pr121133-4.C: New test. (cherry picked from commit fac66b476afccac607dbd9b4e971a42a04666387) --- diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 807fbe5c2fa..7f1f62c76e7 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -2889,7 +2889,7 @@ static size_t cp_parser_skip_std_attribute_spec_seq static size_t cp_parser_skip_attributes_opt (cp_parser *, size_t); static bool cp_parser_extension_opt - (cp_parser *, int *); + (cp_parser *, int *, int *); static void cp_parser_label_declaration (cp_parser *); @@ -9447,11 +9447,12 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk, case RID_EXTENSION: { /* The saved value of the PEDANTIC flag. */ - int saved_pedantic; + int saved_pedantic, saved_long_long; tree expr; /* Save away the PEDANTIC flag. */ - cp_parser_extension_opt (parser, &saved_pedantic); + cp_parser_extension_opt (parser, &saved_pedantic, + &saved_long_long); /* Also suppress -Wconditionally-supported. */ diagnostic_push_diagnostics (global_dc, input_location); diagnostic_classify_diagnostic @@ -9462,6 +9463,7 @@ cp_parser_unary_expression (cp_parser *parser, cp_id_kind * pidk, /* Restore the PEDANTIC flag. */ diagnostic_pop_diagnostics (global_dc, input_location); pedantic = saved_pedantic; + warn_long_long = saved_long_long; return expr; } @@ -15972,15 +15974,16 @@ cp_parser_declaration_seq_opt (cp_parser* parser) static void cp_parser_declaration (cp_parser* parser, tree prefix_attrs) { - int saved_pedantic; + int saved_pedantic, saved_long_long; /* Check for the `__extension__' keyword. */ - if (cp_parser_extension_opt (parser, &saved_pedantic)) + if (cp_parser_extension_opt (parser, &saved_pedantic, &saved_long_long)) { /* Parse the qualified declaration. */ cp_parser_declaration (parser, prefix_attrs); /* Restore the PEDANTIC flag. */ pedantic = saved_pedantic; + warn_long_long = saved_long_long; return; } @@ -16248,15 +16251,16 @@ static void cp_parser_block_declaration (cp_parser *parser, bool statement_p) { - int saved_pedantic; + int saved_pedantic, saved_long_long; /* Check for the `__extension__' keyword. */ - if (cp_parser_extension_opt (parser, &saved_pedantic)) + if (cp_parser_extension_opt (parser, &saved_pedantic, &saved_long_long)) { /* Parse the qualified declaration. */ cp_parser_block_declaration (parser, statement_p); /* Restore the PEDANTIC flag. */ pedantic = saved_pedantic; + warn_long_long = saved_long_long; return; } @@ -28710,16 +28714,17 @@ cp_parser_member_declaration (cp_parser* parser) cp_token *token = NULL; cp_token *decl_spec_token_start = NULL; cp_token *initializer_token_start = NULL; - int saved_pedantic; + int saved_pedantic, saved_long_long; bool saved_colon_corrects_to_scope_p = parser->colon_corrects_to_scope_p; /* Check for the `__extension__' keyword. */ - if (cp_parser_extension_opt (parser, &saved_pedantic)) + if (cp_parser_extension_opt (parser, &saved_pedantic, &saved_long_long)) { /* Recurse. */ cp_parser_member_declaration (parser); /* Restore the old value of the PEDANTIC flag. */ pedantic = saved_pedantic; + warn_long_long = saved_long_long; return; } @@ -31858,13 +31863,16 @@ cp_parser_skip_attributes_opt (cp_parser *parser, size_t n) present, and FALSE otherwise. *SAVED_PEDANTIC is set to the current value of the PEDANTIC flag, regardless of whether or not the `__extension__' keyword is present. The caller is responsible - for restoring the value of the PEDANTIC flag. */ + for restoring the value of the PEDANTIC flag. Similarly *SAVED_LONG_LONG + for warn_long_long flag. */ static bool -cp_parser_extension_opt (cp_parser* parser, int* saved_pedantic) +cp_parser_extension_opt (cp_parser *parser, int *saved_pedantic, + int *saved_long_long) { /* Save the old value of the PEDANTIC flag. */ *saved_pedantic = pedantic; + *saved_long_long = warn_long_long; if (cp_lexer_next_token_is_keyword (parser->lexer, RID_EXTENSION)) { @@ -31873,6 +31881,8 @@ cp_parser_extension_opt (cp_parser* parser, int* saved_pedantic) /* We're not being pedantic while the `__extension__' keyword is in effect. */ pedantic = 0; + /* And we don't want -Wlong-long warning. */ + warn_long_long = 0; return true; } diff --git a/gcc/testsuite/g++.dg/warn/pr121133-1.C b/gcc/testsuite/g++.dg/warn/pr121133-1.C new file mode 100644 index 00000000000..6d6e13bd555 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/pr121133-1.C @@ -0,0 +1,16 @@ +// PR c++/121133 +// { dg-do compile } +// { dg-options "-std=c++98 -Wno-long-long -pedantic-errors" } + +__extension__ typedef long long L; +__extension__ long long a; +struct S { + __extension__ long long b; +}; + +void +foo () +{ + __extension__ long long c; + c = c + (__extension__ (long long) 1); +} diff --git a/gcc/testsuite/g++.dg/warn/pr121133-2.C b/gcc/testsuite/g++.dg/warn/pr121133-2.C new file mode 100644 index 00000000000..cd97a76f511 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/pr121133-2.C @@ -0,0 +1,5 @@ +// PR c++/121133 +// { dg-do compile } +// { dg-options "-std=c++98 -pedantic-errors" } + +#include "pr121133-1.C" diff --git a/gcc/testsuite/g++.dg/warn/pr121133-3.C b/gcc/testsuite/g++.dg/warn/pr121133-3.C new file mode 100644 index 00000000000..9ffd4073484 --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/pr121133-3.C @@ -0,0 +1,5 @@ +// PR c++/121133 +// { dg-do compile { target c++11 } } +// { dg-options "-pedantic-errors" } + +#include "pr121133-1.C" diff --git a/gcc/testsuite/g++.dg/warn/pr121133-4.C b/gcc/testsuite/g++.dg/warn/pr121133-4.C new file mode 100644 index 00000000000..76885ba66bc --- /dev/null +++ b/gcc/testsuite/g++.dg/warn/pr121133-4.C @@ -0,0 +1,5 @@ +// PR c++/121133 +// { dg-do compile { target c++11 } } +// { dg-options "-pedantic-errors -Wlong-long" } + +#include "pr121133-1.C"