]> granicus.if.org Git - clang/commitdiff
[Parse] Make -Wgcc-compat complain about for loop inits in C89
authorGeorge Burgess IV <george.burgess.iv@gmail.com>
Thu, 28 Jun 2018 21:36:00 +0000 (21:36 +0000)
committerGeorge Burgess IV <george.burgess.iv@gmail.com>
Thu, 28 Jun 2018 21:36:00 +0000 (21:36 +0000)
While clang allows declarations in for loop init statements in c89 and
gnu89, gcc does not. So, we should probably warn if users care about gcc
compatibility.

Differential Revision: https://reviews.llvm.org/D47840

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@335927 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Basic/DiagnosticParseKinds.td
lib/Parse/ParseStmt.cpp
test/Parser/gcc-for-loop-init-compatibility.c [new file with mode: 0644]

index c2a1f095f17d7b2e8bab193f73fdcfb341ca53ac..dd4c81922592f4600160fa0581d2f4ff93f2bbfe 100644 (file)
@@ -173,6 +173,9 @@ def warn_attribute_on_function_definition : Warning<
 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>;
index 8c4a3056ec0ec9639118c9b4a1a61e4d5629fc12..107fa556372848339b0a68c0fb7135120fa4c4bf 100644 (file)
@@ -1624,8 +1624,10 @@ StmtResult Parser::ParseForStatement(SourceLocation *TrailingElseLoc) {
     ParenBraceBracketBalancer BalancerRAIIObj(*this);
 
     // 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;
diff --git a/test/Parser/gcc-for-loop-init-compatibility.c b/test/Parser/gcc-for-loop-init-compatibility.c
new file mode 100644 (file)
index 0000000..dc88f08
--- /dev/null
@@ -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@+2{{GCC does not allow variable declarations in for loop initializers before C99}}
+#endif
+  for (int i = 0; i < 10; i++)
+    ;
+}