From eed865ada8669f873c9abdcee9c2818cb17ee550 Mon Sep 17 00:00:00 2001 From: George Burgess IV Date: Thu, 28 Jun 2018 21:36:00 +0000 Subject: [PATCH] [Parse] Make -Wgcc-compat complain about for loop inits in C89 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 | 3 +++ lib/Parse/ParseStmt.cpp | 4 +++- test/Parser/gcc-for-loop-init-compatibility.c | 15 +++++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) create mode 100644 test/Parser/gcc-for-loop-init-compatibility.c diff --git a/include/clang/Basic/DiagnosticParseKinds.td b/include/clang/Basic/DiagnosticParseKinds.td index c2a1f095f1..dd4c819225 100644 --- a/include/clang/Basic/DiagnosticParseKinds.td +++ b/include/clang/Basic/DiagnosticParseKinds.td @@ -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; +def warn_gcc_variable_decl_in_for_loop : Warning< + "GCC does not allow variable declarations in for loop initializers before " + "C99">, InGroup; def warn_attribute_no_decl : Warning< "attribute %0 ignored, because it is not attached to a declaration">, InGroup; diff --git a/lib/Parse/ParseStmt.cpp b/lib/Parse/ParseStmt.cpp index 8c4a3056ec..107fa55637 100644 --- a/lib/Parse/ParseStmt.cpp +++ b/lib/Parse/ParseStmt.cpp @@ -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 index 0000000000..dc88f08395 --- /dev/null +++ b/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@+2{{GCC does not allow variable declarations in for loop initializers before C99}} +#endif + for (int i = 0; i < 10; i++) + ; +} -- 2.40.0