[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 17 14:08:40 PST 2020
aaron.ballman updated this revision to Diff 312613.
aaron.ballman added a comment.
Updating based on review feedback.
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D92577/new/
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
@@ -2,6 +2,12 @@
// Check C99 6.8.5p3
void b1 (void) { for (void (*f) (void);;); }
-void b2 (void) { for (void f (void);;); } // expected-error {{declaration of non-local variable}}
+void b2 (void) { for (void f (void);;); } // expected-error {{non-variable declaration in 'for' loop}}
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 b4 (void) { for (typedef int f;;); } // expected-error {{non-variable declaration in 'for' loop}}
+void b5 (void) { for (struct { int i; } s;;); }
+void b6 (void) { for (enum { zero, ten = 10 } i;;); }
+void b7 (void) { for (struct s { int i; };;); } // expected-error {{non-variable declaration in 'for' loop}}
+void b8 (void) { for (static struct { int i; } s;;); } // expected-error {{declaration of non-local variable}}
+void b9 (void) { for (struct { int i; } (*s)(struct { int j; } o) = 0;;); }
+void b10(void) { for (typedef struct { int i; } (*s)(struct { int j; });;); } // expected-error {{non-variable declaration in 'for' loop}}
Index: clang/lib/Sema/SemaStmt.cpp
===================================================================
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -1822,15 +1822,27 @@
// C99 6.8.5p3: The declaration part of a 'for' statement shall only
// declare identifiers for objects having storage class 'auto' or
// 'register'.
+ const Decl *NonVarSeen = nullptr;
+ bool VarDeclSeen = false;
for (auto *DI : DS->decls()) {
- VarDecl *VD = dyn_cast<VarDecl>(DI);
- if (VD && VD->isLocalVarDecl() && !VD->hasLocalStorage())
- VD = nullptr;
- if (!VD) {
- Diag(DI->getLocation(), diag::err_non_local_variable_decl_in_for);
- DI->setInvalidDecl();
+ if (VarDecl *VD = dyn_cast<VarDecl>(DI)) {
+ VarDeclSeen = true;
+ if (VD->isLocalVarDecl() && !VD->hasLocalStorage()) {
+ Diag(DI->getLocation(), diag::err_non_local_variable_decl_in_for);
+ DI->setInvalidDecl();
+ }
+ } else if (!NonVarSeen) {
+ // Keep track of the first non-variable declaration we saw so that
+ // we can diagnose if we don't see any variable declarations. This
+ // covers a case like declaring a typedef, function, or structure
+ // type rather than a variable.
+ NonVarSeen = DI;
}
}
+ // Diagnose if we saw a non-variable declaration but no variable
+ // declarations.
+ if (NonVarSeen && !VarDeclSeen)
+ Diag(NonVarSeen->getLocation(), diag::err_non_variable_decl_in_for);
}
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D92577.312613.patch
Type: text/x-patch
Size: 2899 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20201217/1d98cba8/attachment.bin>
More information about the cfe-commits
mailing list