zero9178 created this revision.
zero9178 added reviewers: dblaikie, aaron.ballman, rsmith.
zero9178 requested review of this revision.
Herald added a project: clang.
Herald added a subscriber: cfe-commits.
`-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
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D114787
Files:
clang/include/clang/Basic/DiagnosticGroups.td
clang/include/clang/Basic/DiagnosticSemaKinds.td
clang/lib/Sema/SemaStmt.cpp
clang/test/Sema/warn-mixed-decls.c
Index: clang/test/Sema/warn-mixed-decls.c
===================================================================
--- /dev/null
+++ clang/test/Sema/warn-mixed-decls.c
@@ -0,0 +1,11 @@
+/* RUN: %clang_cc1 -fsyntax-only -verify -std=c89 -pedantic %s
+ */
+/* RUN: %clang_cc1 -fsyntax-only -verify -std=c99
-Wdeclaration-after-statement %s
+ */
+
+int foo(int i)
+{
+ i += 1;
+ int f = i; /* expected-warning {{ISO C90 forbids mixing declarations and
code}}*/
+ return f;
+}
Index: clang/lib/Sema/SemaStmt.cpp
===================================================================
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -410,9 +410,10 @@
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 @@
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);
}
}
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9837,7 +9837,10 @@
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<
+ ext_mixed_decls_code.Text>,
+ 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
@@ -239,6 +239,7 @@
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">;
Index: clang/test/Sema/warn-mixed-decls.c
===================================================================
--- /dev/null
+++ clang/test/Sema/warn-mixed-decls.c
@@ -0,0 +1,11 @@
+/* RUN: %clang_cc1 -fsyntax-only -verify -std=c89 -pedantic %s
+ */
+/* RUN: %clang_cc1 -fsyntax-only -verify -std=c99 -Wdeclaration-after-statement %s
+ */
+
+int foo(int i)
+{
+ i += 1;
+ int f = i; /* expected-warning {{ISO C90 forbids mixing declarations and code}}*/
+ return f;
+}
Index: clang/lib/Sema/SemaStmt.cpp
===================================================================
--- clang/lib/Sema/SemaStmt.cpp
+++ clang/lib/Sema/SemaStmt.cpp
@@ -410,9 +410,10 @@
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 @@
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);
}
}
Index: clang/include/clang/Basic/DiagnosticSemaKinds.td
===================================================================
--- clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -9837,7 +9837,10 @@
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<
+ ext_mixed_decls_code.Text>,
+ 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
@@ -239,6 +239,7 @@
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">;
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits