[PATCH] D92577: Don't reject tag declarations in for loop clause-1

Aaron Ballman via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 3 07:33:46 PST 2020


aaron.ballman created this revision.
aaron.ballman added reviewers: rsmith, rjmccall.
aaron.ballman requested review of this revision.

We currently reject this valid C construct by claiming it declares a non-local variable: `for (struct { int i; } s={0}; s.i != 0; s.i--) ;`

The problem is that we expect all declaration in the clause-1 declaration statement to be `VarDecl`s of local variables, but there can be other declarations involved such as a tag declaration. We now ignore tag declarations when deciding whether the clause-1 declarations are valid or not. This fixes PR35757.


https://reviews.llvm.org/D92577

Files:
  clang/lib/Sema/SemaStmt.cpp
  clang/test/Sema/for.c


Index: clang/test/Sema/for.c
===================================================================
--- clang/test/Sema/for.c
+++ clang/test/Sema/for.c
@@ -5,3 +5,5 @@
 void b2 (void) { for (void f (void);;); }   // expected-error {{declaration of non-local variable}}
 void b3 (void) { for (static int f;;); }    // expected-error {{declaration of non-local variable}}
 void b4 (void) { for (typedef int f;;); }   // expected-error {{declaration of non-local variable}}
+void b5 (void) { for (struct { int i; } s;;); }
+void b6 (void) { for (enum { zero, ten = 10 } i;;); }
Index: clang/lib/Sema/SemaStmt.cpp
===================================================================
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -1826,7 +1826,10 @@
         VarDecl *VD = dyn_cast<VarDecl>(DI);
         if (VD && VD->isLocalVarDecl() && !VD->hasLocalStorage())
           VD = nullptr;
-        if (!VD) {
+        // It is possible to declare non-variable declarations as part of the
+        // declaration part of a 'for' statement, such as defining a structure
+        // or enum type: for (enum { zero, ten } i = zero; i < ten; ++i);
+        if (!VD && !isa<TagDecl>(DI)) {
           Diag(DI->getLocation(), diag::err_non_local_variable_decl_in_for);
           DI->setInvalidDecl();
         }


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D92577.309251.patch
Type: text/x-patch
Size: 1317 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20201203/b399ade9/attachment.bin>


More information about the cfe-commits mailing list