]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c: Remove restrictions on declarations in 'for' loops for C2X
authorJoseph Myers <joseph@codesourcery.com>
Tue, 16 May 2023 23:44:56 +0000 (23:44 +0000)
committerJoseph Myers <joseph@codesourcery.com>
Tue, 16 May 2023 23:46:02 +0000 (23:46 +0000)
C2X removes a restriction that the only declarations in the
declaration part of a 'for' loop are declarations of objects with
storage class auto or register.  Implement this change, making the
diagnostics into pedwarn_c11 calls instead of errors (as usual for
features added in a new standard version that were invalid code in a
previous version), so now pedwarn-if-pedantic for older standards and
diagnosed also with -Wc11-c2x-compat.

Bootstrapped with no regressions for x86_64-pc-linux-gnu.

gcc/c/
* c-decl.cc (check_for_loop_decls): Use pedwarn_c11 for
diagnostics.

gcc/testsuite/
* gcc.dg/c11-fordecl-1.c, gcc.dg/c11-fordecl-2.c,
gcc.dg/c11-fordecl-3.c, gcc.dg/c11-fordecl-4.c,
gcc.dg/c2x-fordecl-1.c, gcc.dg/c2x-fordecl-2.c,
gcc.dg/c2x-fordecl-3.c, gcc.dg/c2x-fordecl-4.c: New tests.
* gcc.dg/c99-fordecl-2.c: Test diagnostic for typedef declaration
in for loop here.
* gcc.dg/pr67784-2.c, gcc.dg/pr68320.c, objc.dg/foreach-7.m: Do
not expect errors for typedef declaration in for loop.

13 files changed:
gcc/c/c-decl.cc
gcc/testsuite/gcc.dg/c11-fordecl-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c11-fordecl-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c11-fordecl-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c11-fordecl-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c2x-fordecl-1.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c2x-fordecl-2.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c2x-fordecl-3.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c2x-fordecl-4.c [new file with mode: 0644]
gcc/testsuite/gcc.dg/c99-fordecl-2.c
gcc/testsuite/gcc.dg/pr67784-2.c
gcc/testsuite/gcc.dg/pr68320.c
gcc/testsuite/objc.dg/foreach-7.m

index 90d7cd27cd5ab6ab2356694bba26c21ea492d858..f8ede362bfd70324fd49a2fbdf70e42e5e6b1c84 100644 (file)
@@ -11032,7 +11032,9 @@ check_for_loop_decls (location_t loc, bool turn_off_iso_c99_error)
      only applies to those that are.  (A question on this in comp.std.c
      in November 2000 received no answer.)  We implement the strictest
      interpretation, to avoid creating an extension which later causes
-     problems.  */
+     problems.
+
+     This constraint was removed in C2X.  */
 
   for (b = current_scope->bindings; b; b = b->prev)
     {
@@ -11048,33 +11050,35 @@ check_for_loop_decls (location_t loc, bool turn_off_iso_c99_error)
          {
            location_t decl_loc = DECL_SOURCE_LOCATION (decl);
            if (TREE_STATIC (decl))
-             error_at (decl_loc,
-                       "declaration of static variable %qD in %<for%> loop "
-                       "initial declaration", decl);
+             pedwarn_c11 (decl_loc, OPT_Wpedantic,
+                          "declaration of static variable %qD in %<for%> "
+                          "loop initial declaration", decl);
            else if (DECL_EXTERNAL (decl))
-             error_at (decl_loc,
-                       "declaration of %<extern%> variable %qD in %<for%> loop "
-                       "initial declaration", decl);
+             pedwarn_c11 (decl_loc, OPT_Wpedantic,
+                          "declaration of %<extern%> variable %qD in %<for%> "
+                          "loop initial declaration", decl);
          }
          break;
 
        case RECORD_TYPE:
-         error_at (loc,
-                   "%<struct %E%> declared in %<for%> loop initial "
-                   "declaration", id);
+         pedwarn_c11 (loc, OPT_Wpedantic,
+                      "%<struct %E%> declared in %<for%> loop initial "
+                      "declaration", id);
          break;
        case UNION_TYPE:
-         error_at (loc,
-                   "%<union %E%> declared in %<for%> loop initial declaration",
-                   id);
+         pedwarn_c11 (loc, OPT_Wpedantic,
+                      "%<union %E%> declared in %<for%> loop initial "
+                      "declaration",
+                      id);
          break;
        case ENUMERAL_TYPE:
-         error_at (loc, "%<enum %E%> declared in %<for%> loop "
-                   "initial declaration", id);
+         pedwarn_c11 (loc, OPT_Wpedantic,
+                      "%<enum %E%> declared in %<for%> loop "
+                      "initial declaration", id);
          break;
        default:
-         error_at (loc, "declaration of non-variable "
-                   "%qD in %<for%> loop initial declaration", decl);
+         pedwarn_c11 (loc, OPT_Wpedantic, "declaration of non-variable "
+                      "%qD in %<for%> loop initial declaration", decl);
        }
 
       n_decls++;
diff --git a/gcc/testsuite/gcc.dg/c11-fordecl-1.c b/gcc/testsuite/gcc.dg/c11-fordecl-1.c
new file mode 100644 (file)
index 0000000..4aceb33
--- /dev/null
@@ -0,0 +1,27 @@
+/* Test for C99 declarations in for loops.  Test constraints are diagnosed for
+   C11.  Based on c99-fordecl-2.c.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+void
+foo (void)
+{
+  int j = 0;
+  for (int i = 1, bar (void); i <= 10; i++) /* { dg-error "bar" } */
+    j += i;
+
+  for (static int i = 1; i <= 10; i++) /* /* { dg-error "static" } */
+    j += i;
+
+  for (extern int i; j <= 500; j++) /* { dg-error "extern" } */
+    j += 5;
+
+  for (enum { FOO } i = FOO; i < 10; i++) /* { dg-error "FOO" } */
+    j += i;
+
+  for (enum BAR { FOO } i = FOO; i < 10; i++) /* { dg-error "FOO" } */
+    /* { dg-error "BAR" "enum tag in for loop" { target *-*-* } .-1 } */
+    j += i;
+  for (typedef int T;;) /* { dg-error "non-variable" } */
+    ;
+}
diff --git a/gcc/testsuite/gcc.dg/c11-fordecl-2.c b/gcc/testsuite/gcc.dg/c11-fordecl-2.c
new file mode 100644 (file)
index 0000000..0be1a0d
--- /dev/null
@@ -0,0 +1,14 @@
+/* Test for C99 declarations in for loops.  Test constraints are diagnosed for
+   C11: struct and union tags can't be declared there (affirmed in response to
+   DR#277).  Based on c99-fordecl-3.c.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic-errors" } */
+
+void
+foo (void)
+{
+  for (struct s { int p; } *p = 0; ;) /* { dg-error "'struct s' declared in 'for' loop initial declaration" } */
+    ;
+  for (union u { int p; } *p = 0; ;) /* { dg-error "'union u' declared in 'for' loop initial declaration" } */
+    ;
+}
diff --git a/gcc/testsuite/gcc.dg/c11-fordecl-3.c b/gcc/testsuite/gcc.dg/c11-fordecl-3.c
new file mode 100644 (file)
index 0000000..28ef629
--- /dev/null
@@ -0,0 +1,6 @@
+/* Test restrictions on the kind of declarations permitted in for loops removed
+   in C2X, and thus with -std=c11 -pedantic -Wno-c11-c2x-compat.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic -Wno-c11-c2x-compat" } */
+
+#include "c99-fordecl-2.c"
diff --git a/gcc/testsuite/gcc.dg/c11-fordecl-4.c b/gcc/testsuite/gcc.dg/c11-fordecl-4.c
new file mode 100644 (file)
index 0000000..2a352d6
--- /dev/null
@@ -0,0 +1,6 @@
+/* Test restrictions on the kind of declarations permitted in for loops removed
+   in C2X, and thus with -std=c11 -pedantic -Wno-c11-c2x-compat.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c11 -pedantic -Wno-c11-c2x-compat" } */
+
+#include "c99-fordecl-3.c"
diff --git a/gcc/testsuite/gcc.dg/c2x-fordecl-1.c b/gcc/testsuite/gcc.dg/c2x-fordecl-1.c
new file mode 100644 (file)
index 0000000..563186f
--- /dev/null
@@ -0,0 +1,6 @@
+/* Test restrictions on the kind of declarations permitted in for loops removed
+   in C2X.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include "c99-fordecl-2.c"
diff --git a/gcc/testsuite/gcc.dg/c2x-fordecl-2.c b/gcc/testsuite/gcc.dg/c2x-fordecl-2.c
new file mode 100644 (file)
index 0000000..4250190
--- /dev/null
@@ -0,0 +1,6 @@
+/* Test restrictions on the kind of declarations permitted in for loops removed
+   in C2X.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors" } */
+
+#include "c99-fordecl-3.c"
diff --git a/gcc/testsuite/gcc.dg/c2x-fordecl-3.c b/gcc/testsuite/gcc.dg/c2x-fordecl-3.c
new file mode 100644 (file)
index 0000000..d39d4a6
--- /dev/null
@@ -0,0 +1,27 @@
+/* Test for C99 declarations in for loops.  Test constraints are diagnosed with
+   -Wc11-c2x-compat for C2X.  Based on c99-fordecl-2.c.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors -Wc11-c2x-compat" } */
+
+void
+foo (void)
+{
+  int j = 0;
+  for (int i = 1, bar (void); i <= 10; i++) /* { dg-warning "bar" } */
+    j += i;
+
+  for (static int i = 1; i <= 10; i++) /* /* { dg-warning "static" } */
+    j += i;
+
+  for (extern int i; j <= 500; j++) /* { dg-warning "extern" } */
+    j += 5;
+
+  for (enum { FOO } i = FOO; i < 10; i++) /* { dg-warning "FOO" } */
+    j += i;
+
+  for (enum BAR { FOO } i = FOO; i < 10; i++) /* { dg-warning "FOO" } */
+    /* { dg-warning "BAR" "enum tag in for loop" { target *-*-* } .-1 } */
+    j += i;
+  for (typedef int T;;) /* { dg-warning "non-variable" } */
+    ;
+}
diff --git a/gcc/testsuite/gcc.dg/c2x-fordecl-4.c b/gcc/testsuite/gcc.dg/c2x-fordecl-4.c
new file mode 100644 (file)
index 0000000..e9dfc4b
--- /dev/null
@@ -0,0 +1,14 @@
+/* Test for C99 declarations in for loops.  Test constraints are diagnosed with
+   -Wc11-c2x-compat for C2X: struct and union tags can't be declared there
+   (affirmed in response to DR#277).  Based on c99-fordecl-3.c.  */
+/* { dg-do compile } */
+/* { dg-options "-std=c2x -pedantic-errors -Wc11-c2x-compat" } */
+
+void
+foo (void)
+{
+  for (struct s { int p; } *p = 0; ;) /* { dg-warning "'struct s' declared in 'for' loop initial declaration" } */
+    ;
+  for (union u { int p; } *p = 0; ;) /* { dg-warning "'union u' declared in 'for' loop initial declaration" } */
+    ;
+}
index aa5bc783ff801eac0192b281ba7fc5ceaab24f6c..a8d5b124fb65ec17f3a6276da86ab9eaacedb420 100644 (file)
@@ -29,4 +29,6 @@ foo (void)
     /* { dg-error "FOO" "enum value in for loop" { target *-*-* } .-1 } */
     /* { dg-error "BAR" "enum tag in for loop" { target *-*-* } .-2 } */
     j += i;
+  for (typedef int T;;) /* { dg-error "non-variable" } */
+    ;
 }
index de3b1c89a89cd267bba0327be0d6728bdac8b605..07af9cbcb82a2ce830443ae1f36ff75fba026e76 100644 (file)
@@ -7,7 +7,7 @@ int T;
 void
 fn1 (void)
 {
-  for (typedef int T;;) /* { dg-error "declaration of non-variable" } */
+  for (typedef int T;;)
     if (1)
       ;
   T *x; /* { dg-error "undeclared" } */
@@ -16,7 +16,7 @@ fn1 (void)
 void
 fn2 (void)
 {
-  for (typedef int T;;) /* { dg-error "declaration of non-variable" } */
+  for (typedef int T;;)
     if (1)
       T = 1; /* { dg-error "expected expression" } */
   T *x; /* { dg-error "undeclared" } */
@@ -25,7 +25,7 @@ fn2 (void)
 void
 fn3 (void)
 {
-  for (typedef int T;;) /* { dg-error "declaration of non-variable" } */
+  for (typedef int T;;)
     if (1)
       {
       }
@@ -35,7 +35,7 @@ fn3 (void)
 void
 fn4 (void)
 {
-  for (typedef int T;;) /* { dg-error "declaration of non-variable" } */
+  for (typedef int T;;)
     if (1)
 L:
       ;
@@ -45,7 +45,7 @@ L:
 void
 fn5 (void)
 {
-  for (typedef int T;;) /* { dg-error "declaration of non-variable" } */
+  for (typedef int T;;)
     if (1)
       ;
     else
index 7060af8993eb7b128dd4886462213e48d8566bcf..5d891b9bb1ed387196179b7cebe851d5211f5bf3 100644 (file)
@@ -5,7 +5,7 @@
 void
 fn1 (void)
 {
-  for (typedef int T;;) /* { dg-error "declaration of non-variable" } */
+  for (typedef int T;;)
     if (1)
       ;
   T x; /* { dg-error "unknown type name" } */
@@ -14,7 +14,7 @@ fn1 (void)
 void
 fn2 (int i)
 {
-  for (typedef int T;;) /* { dg-error "declaration of non-variable" } */
+  for (typedef int T;;)
     if (1)
       i = 5;
   T x; /* { dg-error "unknown type name" } */
@@ -23,7 +23,7 @@ fn2 (int i)
 void
 fn3 (void)
 {
-  for (typedef int T;;) /* { dg-error "declaration of non-variable" } */
+  for (typedef int T;;)
     if (1)
       {
       }
@@ -33,7 +33,7 @@ fn3 (void)
 void
 fn4 (void)
 {
-  for (typedef int T;;) /* { dg-error "declaration of non-variable" } */
+  for (typedef int T;;)
     if (1)
       ;
   T, T; /* { dg-error "undeclared" } */
@@ -42,7 +42,7 @@ fn4 (void)
 void
 fn5 (void)
 {
-  for (typedef int T;;) /* { dg-error "declaration of non-variable" } */
+  for (typedef int T;;)
     if (1)
       ;
   T = 10; /* { dg-error "undeclared" } */
@@ -51,7 +51,7 @@ fn5 (void)
 void
 fn6 (void)
 {
-  for (typedef int T;;) /* { dg-error "declaration of non-variable" } */
+  for (typedef int T;;)
     if (1)
       ;
   T[0]; /* { dg-error "undeclared" } */
@@ -60,7 +60,7 @@ fn6 (void)
 void
 fn7 (void)
 {
-  for (typedef int T;;) /* { dg-error "declaration of non-variable" } */
+  for (typedef int T;;)
     if (1)
       ;
   T (); /* { dg-warning "implicit declaration" } */
index 7ceff075016a1bfe94d3bff5afa3150b108b0203..c8e817f258cc5d3c2ef25425ba0aa80cacfa446b 100644 (file)
@@ -39,7 +39,7 @@ int main (void)
   id array = nil;
   id object = nil;
 
-  for (typedef int my_typedef in array) /* { dg-error "declaration of non-variable" } */
+  for (typedef int my_typedef in array)
     ;                                   /* { dg-error "iterating variable in fast enumeration is not an object" "" { target *-*-* } .-1 } */
 
   for (function () in nil) /* { dg-error "invalid iterating variable in fast enumeration" } */