https://gcc.gnu.org/g:fac66b476afccac607dbd9b4e971a42a04666387
commit r16-2635-gfac66b476afccac607dbd9b4e971a42a04666387 Author: Jakub Jelinek <ja...@redhat.com> Date: Wed Jul 30 13:23:56 2025 +0200 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 <ja...@redhat.com> 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. Diff: --- gcc/cp/parser.cc | 32 +++++++++++++++++++++----------- gcc/testsuite/g++.dg/warn/pr121133-1.C | 16 ++++++++++++++++ gcc/testsuite/g++.dg/warn/pr121133-2.C | 5 +++++ gcc/testsuite/g++.dg/warn/pr121133-3.C | 5 +++++ gcc/testsuite/g++.dg/warn/pr121133-4.C | 5 +++++ 5 files changed, 52 insertions(+), 11 deletions(-) diff --git a/gcc/cp/parser.cc b/gcc/cp/parser.cc index 9e9cd9be54d1..eb66427a85db 100644 --- a/gcc/cp/parser.cc +++ b/gcc/cp/parser.cc @@ -2921,7 +2921,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 *); @@ -9504,11 +9504,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 @@ -9519,6 +9520,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; } @@ -16047,15 +16049,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; } @@ -16323,15 +16326,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; } @@ -28869,16 +28873,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; } @@ -32020,13 +32025,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)) { @@ -32035,6 +32043,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 000000000000..6d6e13bd5557 --- /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 000000000000..cd97a76f5114 --- /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 000000000000..9ffd40734845 --- /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 000000000000..76885ba66bcf --- /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"