]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: Make __extension__ silence -Wlong-long pedwarns/warnings [PR121133]
authorJakub Jelinek <jakub@redhat.com>
Wed, 30 Jul 2025 11:23:56 +0000 (13:23 +0200)
committerJakub Jelinek <jakub@gcc.gnu.org>
Wed, 30 Jul 2025 12:49:53 +0000 (14:49 +0200)
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  <jakub@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.

(cherry picked from commit fac66b476afccac607dbd9b4e971a42a04666387)

gcc/cp/parser.cc
gcc/testsuite/g++.dg/warn/pr121133-1.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/pr121133-2.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/pr121133-3.C [new file with mode: 0644]
gcc/testsuite/g++.dg/warn/pr121133-4.C [new file with mode: 0644]

index 807fbe5c2fa8ee813d02d4d475de768e311ae4fe..7f1f62c76e7cc3637a36cab33cf31bec1272867b 100644 (file)
@@ -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 (file)
index 0000000..6d6e13b
--- /dev/null
@@ -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 (file)
index 0000000..cd97a76
--- /dev/null
@@ -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 (file)
index 0000000..9ffd407
--- /dev/null
@@ -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 (file)
index 0000000..76885ba
--- /dev/null
@@ -0,0 +1,5 @@
+// PR c++/121133
+// { dg-do compile { target c++11 } }
+// { dg-options "-pedantic-errors -Wlong-long" }
+
+#include "pr121133-1.C"