[PATCH] D47840: Make -Wgcc-compat complain about declarations in for loop init statements
George Burgess IV via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed Jun 6 11:59:54 PDT 2018
george.burgess.iv created this revision.
george.burgess.iv added reviewers: rsmith, aaron.ballman.
The following code is invalid before C99, since we try to declare `i` inside the first clause of the for loop:
void foo() {
for (int i = 0; i < 10; i++);
}
GCC does not accept this code in c89 or gnu89, but clang does: https://godbolt.org/g/ZWr3nA .
If the user cares about GCC compatibility, we should probably warn about this if we're not in C99.
I'm not 100% thrilled that we're emitting two warnings about the same thing for slightly different reasons; alternatives welcome. :)
Repository:
rC Clang
https://reviews.llvm.org/D47840
Files:
include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/ParseStmt.cpp
test/Parser/gcc-for-loop-init-compatibility.c
Index: test/Parser/gcc-for-loop-init-compatibility.c
===================================================================
--- /dev/null
+++ test/Parser/gcc-for-loop-init-compatibility.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -std=c89 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=gnu89 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -std=c99 -fsyntax-only -verify %s -DC99
+
+#ifdef C99
+// expected-no-diagnostics
+#endif
+
+void foo() {
+#ifndef C99
+ // expected-warning at +2{{GCC does not allow variable declarations in for loop initializers before C99}}
+#endif
+ for (int i = 0; i < 10; i++)
+ ;
+}
Index: lib/Parse/ParseStmt.cpp
===================================================================
--- lib/Parse/ParseStmt.cpp
+++ lib/Parse/ParseStmt.cpp
@@ -1622,8 +1622,10 @@
ForRange = true;
} else if (isForInitDeclaration()) { // for (int X = 4;
// Parse declaration, which eats the ';'.
- if (!C99orCXXorObjC) // Use of C99-style for loops in C90 mode?
+ if (!C99orCXXorObjC) { // Use of C99-style for loops in C90 mode?
Diag(Tok, diag::ext_c99_variable_decl_in_for_loop);
+ Diag(Tok, diag::warn_gcc_variable_decl_in_for_loop);
+ }
// In C++0x, "for (T NS:a" might not be a typo for ::
bool MightBeForRangeStmt = getLangOpts().CPlusPlus;
Index: include/clang/Basic/DiagnosticParseKinds.td
===================================================================
--- include/clang/Basic/DiagnosticParseKinds.td
+++ include/clang/Basic/DiagnosticParseKinds.td
@@ -173,6 +173,9 @@
def warn_gcc_attribute_location : Warning<
"GCC does not allow an attribute in this position on a function declaration">,
InGroup<GccCompat>;
+def warn_gcc_variable_decl_in_for_loop : Warning<
+ "GCC does not allow variable declarations in for loop initializers before "
+ "C99">, InGroup<GccCompat>;
def warn_attribute_no_decl : Warning<
"attribute %0 ignored, because it is not attached to a declaration">,
InGroup<IgnoredAttributes>;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D47840.150167.patch
Type: text/x-patch
Size: 1992 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180606/dda68111/attachment.bin>
More information about the cfe-commits
mailing list