[clang] 118f966 - [clang][#51931] Enable `-Wdeclaration-after-statement` for all C versions

Markus Böck via cfe-commits cfe-commits at lists.llvm.org
Wed Jan 12 09:21:53 PST 2022


Author: Markus Böck
Date: 2022-01-12T18:21:46+01:00
New Revision: 118f966b46cfb60897b56a9878e1c68fd0e2afa4

URL: https://github.com/llvm/llvm-project/commit/118f966b46cfb60897b56a9878e1c68fd0e2afa4
DIFF: https://github.com/llvm/llvm-project/commit/118f966b46cfb60897b56a9878e1c68fd0e2afa4.diff

LOG: [clang][#51931] Enable `-Wdeclaration-after-statement` for all C versions

-Wdeclaration-after-statement currently only outputs an diagnostic if the user is compiling in C versions older than C99, even if the warning was explicitly requested by the user.
This patch makes the warning also available in later C versions. If the C version is C99 or later it is simply a normal warning that is disabled by default (as it is valid C99) and has to be enabled by users. In older versions it remains an extension warning, and therefore affected by -pedantic.

The above behaviour also matches GCCs behaviour.

Fixes https://bugs.llvm.org/show_bug.cgi?id=51931

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

Added: 
    clang/test/Sema/warn-mixed-decls.c

Modified: 
    clang/include/clang/Basic/DiagnosticGroups.td
    clang/include/clang/Basic/DiagnosticSemaKinds.td
    clang/lib/Sema/SemaStmt.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/DiagnosticGroups.td b/clang/include/clang/Basic/DiagnosticGroups.td
index c0642efaee4e..1bc879a68a8c 100644
--- a/clang/include/clang/Basic/DiagnosticGroups.td
+++ b/clang/include/clang/Basic/DiagnosticGroups.td
@@ -241,6 +241,7 @@ def Documentation : DiagGroup<"documentation",
 
 def EmptyBody : DiagGroup<"empty-body">;
 def Exceptions : DiagGroup<"exceptions">;
+def DeclarationAfterStatement : DiagGroup<"declaration-after-statement">;
 
 def GNUEmptyInitializer : DiagGroup<"gnu-empty-initializer">;
 def GNUEmptyStruct : DiagGroup<"gnu-empty-struct">;

diff  --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index dfd1069096ea..19ce0ffcec51 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9861,8 +9861,11 @@ def err_constant_integer_arg_type : Error<
   "argument to %0 must be a constant integer">;
 
 def ext_mixed_decls_code : Extension<
-  "ISO C90 forbids mixing declarations and code">,
-  InGroup<DiagGroup<"declaration-after-statement">>;
+  "mixing declarations and code is a C99 extension">,
+  InGroup<DeclarationAfterStatement>;
+def warn_mixed_decls_code : Warning<
+  "mixing declarations and code is incompatible with standards before C99">,
+  InGroup<DeclarationAfterStatement>, DefaultIgnore;
 
 def err_non_local_variable_decl_in_for : Error<
   "declaration of non-local variable in 'for' loop">;

diff  --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 7fe92f492b5e..ef498f9a5228 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -410,9 +410,10 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
                                    ArrayRef<Stmt *> Elts, bool isStmtExpr) {
   const unsigned NumElts = Elts.size();
 
-  // If we're in C89 mode, check that we don't have any decls after stmts.  If
-  // so, emit an extension diagnostic.
-  if (!getLangOpts().C99 && !getLangOpts().CPlusPlus) {
+  // If we're in C mode, check that we don't have any decls after stmts.  If
+  // so, emit an extension diagnostic in C89 and potentially a warning in later
+  // versions.
+  if (!getLangOpts().CPlusPlus) {
     // Note that __extension__ can be around a decl.
     unsigned i = 0;
     // Skip over all declarations.
@@ -425,7 +426,8 @@ StmtResult Sema::ActOnCompoundStmt(SourceLocation L, SourceLocation R,
 
     if (i != NumElts) {
       Decl *D = *cast<DeclStmt>(Elts[i])->decl_begin();
-      Diag(D->getLocation(), diag::ext_mixed_decls_code);
+      Diag(D->getLocation(), !getLangOpts().C99 ? diag::ext_mixed_decls_code
+                                                : diag::warn_mixed_decls_code);
     }
   }
 

diff  --git a/clang/test/Sema/warn-mixed-decls.c b/clang/test/Sema/warn-mixed-decls.c
new file mode 100644
index 000000000000..219d64472b58
--- /dev/null
+++ b/clang/test/Sema/warn-mixed-decls.c
@@ -0,0 +1,28 @@
+/* RUN: %clang_cc1 -fsyntax-only -verify -std=c89 -pedantic %s
+ */
+/* RUN: %clang_cc1 -fsyntax-only -verify -std=c99 -Wdeclaration-after-statement %s
+ */
+
+/* Should not emit diagnostic when not pedantic, not enabled or in C++ Code*/
+/* RUN: %clang_cc1 -fsyntax-only -verify=none -std=c89 %s
+ */
+/* RUN: %clang_cc1 -fsyntax-only -verify=none -std=c99 %s
+ */
+/* RUN: %clang_cc1 -fsyntax-only -verify=none -x c++ %s
+ */
+/* RUN: %clang_cc1 -fsyntax-only -verify=none -x c++ -Wdeclaration-after-statement %s
+ */
+
+/* none-no-diagnostics */
+
+int foo(int i)
+{
+  i += 1;
+  int f = i;
+#if __STDC_VERSION__ < 199901L
+  /* expected-warning at -2 {{mixing declarations and code is a C99 extension}}*/
+#else
+  /* expected-warning at -4 {{mixing declarations and code is incompatible with standards before C99}}*/
+#endif
+  return f;
+}


        


More information about the cfe-commits mailing list