Hi!

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).

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

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-29  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.

--- gcc/cp/parser.cc.jj 2025-07-27 23:31:09.730006891 +0200
+++ gcc/cp/parser.cc    2025-07-28 14:15:05.450578933 +0200
@@ -2921,7 +2921,7 @@ static size_t cp_parser_skip_std_attribu
 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 *p
        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 *p
            /* 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
 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*
   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
    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* pars
       /* 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;
     }
--- gcc/testsuite/g++.dg/warn/pr121133-1.C.jj   2025-07-28 14:35:06.847066122 
+0200
+++ gcc/testsuite/g++.dg/warn/pr121133-1.C      2025-07-28 15:07:31.648968490 
+0200
@@ -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);
+}
--- gcc/testsuite/g++.dg/warn/pr121133-2.C.jj   2025-07-28 14:35:36.996677078 
+0200
+++ gcc/testsuite/g++.dg/warn/pr121133-2.C      2025-07-28 14:36:43.821814791 
+0200
@@ -0,0 +1,5 @@
+// PR c++/121133
+// { dg-do compile }
+// { dg-options "-std=c++98 -pedantic-errors" }
+
+#include "pr121133-1.C"
--- gcc/testsuite/g++.dg/warn/pr121133-3.C.jj   2025-07-28 14:36:56.196655111 
+0200
+++ gcc/testsuite/g++.dg/warn/pr121133-3.C      2025-07-28 14:37:36.997128637 
+0200
@@ -0,0 +1,5 @@
+// PR c++/121133
+// { dg-do compile { target c++11 } }
+// { dg-options "-pedantic-errors" }
+
+#include "pr121133-1.C"
--- gcc/testsuite/g++.dg/warn/pr121133-4.C.jj   2025-07-28 14:37:45.208022686 
+0200
+++ gcc/testsuite/g++.dg/warn/pr121133-4.C      2025-07-28 14:38:06.653745963 
+0200
@@ -0,0 +1,5 @@
+// PR c++/121133
+// { dg-do compile { target c++11 } }
+// { dg-options "-pedantic-errors -Wlong-long" }
+
+#include "pr121133-1.C"

        Jakub

Reply via email to