[PATCH] D117232: [clang] Respect -Wdeclaration-after-statement with C99 or later

Marco Elver via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Jan 13 08:48:58 PST 2022


melver created this revision.
melver added reviewers: aaron.ballman, dblaikie, rsmith.
melver requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.

GCC allows using -Wdeclaration-after-statement to warn when mixing code
and declarations not just with C89, but also C99 and later.

Because the warning may legitimately be used where a codebase's style
forbids mixing declarations and code, Clang should match GCC behaviour.
For example, the Linux kernel is one such codebase, and having this
warning work is a requirement for moving to newer standards.

Fix it by introducing a matching warning, and switching between the
extension or warning depending on the C standard used.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D117232

Files:
  clang/include/clang/Basic/DiagnosticGroups.td
  clang/include/clang/Basic/DiagnosticSemaKinds.td
  clang/lib/Sema/SemaStmt.cpp
  clang/test/Sema/warn-mixed-decls-code.c


Index: clang/test/Sema/warn-mixed-decls-code.c
===================================================================
--- /dev/null
+++ clang/test/Sema/warn-mixed-decls-code.c
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c89 -fsyntax-only -verify -Wall -Wno-comment -DSILENCE %s
+// RUN: %clang_cc1 -std=c99 -fsyntax-only -verify -Wall -pedantic -DSILENCE %s
+// RUN: %clang_cc1 -std=c11 -fsyntax-only -verify -Wall -pedantic -DSILENCE %s
+// RUN: %clang_cc1 -std=c89 -fsyntax-only -verify -Wno-comment -pedantic %s
+// RUN: %clang_cc1 -std=c89 -fsyntax-only -verify -Wno-comment -Wdeclaration-after-statement %s
+// RUN: %clang_cc1 -std=c99 -fsyntax-only -verify -Wdeclaration-after-statement %s
+// RUN: %clang_cc1 -std=c11 -fsyntax-only -verify -Wdeclaration-after-statement %s
+
+#ifdef SILENCE
+  // expected-no-diagnostics
+#endif
+
+void foo(void);
+
+void test1(void) {
+  int a;
+  foo();
+  int b;
+#ifndef SILENCE
+  // expected-warning at -2 {{mixing declarations and code}}
+#endif
+  (void)a;
+  (void)b;
+}
Index: clang/lib/Sema/SemaStmt.cpp
===================================================================
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -410,9 +410,12 @@
                                    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 C89 mode or have -Wdeclaration-after-statement, check that we
+  // don't have any decls after stmts.  If so, emit an extension diagnostic.
+  const unsigned MixedDeclsCodeID = getLangOpts().C99
+                                        ? diag::warn_mixed_decls_code
+                                        : diag::ext_mixed_decls_code;
+  if (!getLangOpts().CPlusPlus && !Diags.isIgnored(MixedDeclsCodeID, L)) {
     // Note that __extension__ can be around a decl.
     unsigned i = 0;
     // Skip over all declarations.
@@ -425,7 +428,7 @@
 
     if (i != NumElts) {
       Decl *D = *cast<DeclStmt>(Elts[i])->decl_begin();
-      Diag(D->getLocation(), diag::ext_mixed_decls_code);
+      Diag(D->getLocation(), MixedDeclsCodeID);
     }
   }
 
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9862,7 +9862,9 @@
 
 def ext_mixed_decls_code : Extension<
   "ISO C90 forbids mixing declarations and code">,
-  InGroup<DiagGroup<"declaration-after-statement">>;
+  InGroup<DeclarationAfterStatement>;
+def warn_mixed_decls_code : Warning<"mixing declarations and code">,
+  InGroup<DeclarationAfterStatement>, DefaultIgnore;
 
 def err_non_local_variable_decl_in_for : Error<
   "declaration of non-local variable in 'for' loop">;
Index: clang/include/clang/Basic/DiagnosticGroups.td
===================================================================
--- clang/include/clang/Basic/DiagnosticGroups.td
+++ clang/include/clang/Basic/DiagnosticGroups.td
@@ -54,6 +54,7 @@
                                     CompoundTokenSplitBySpace]>;
 def CoroutineMissingUnhandledException :
   DiagGroup<"coroutine-missing-unhandled-exception">;
+def DeclarationAfterStatement : DiagGroup<"declaration-after-statement">;
 def DeprecatedExperimentalCoroutine :
   DiagGroup<"deprecated-experimental-coroutine">;
 def DeprecatedCoroutine :


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D117232.399688.patch
Type: text/x-patch
Size: 3529 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20220113/3d8774c7/attachment.bin>


More information about the cfe-commits mailing list