summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2007-08-27 04:29:41 +0000
committerChris Lattner <sabre@nondot.org>2007-08-27 04:29:41 +0000
commitd864daf5c6b96ec3f1ebc3e6d5ad43cc452fe407 (patch)
tree8505d5d42dbad08fa6b76c76e75c83c8dd5063d3 /clang
parent808eb8fe88f968b338e5cf86ce0922ac4c485e56 (diff)
downloadbcm5719-llvm-d864daf5c6b96ec3f1ebc3e6d5ad43cc452fe407.tar.gz
bcm5719-llvm-d864daf5c6b96ec3f1ebc3e6d5ad43cc452fe407.zip
extwarn about decls intermixed with code in c89 mode.
llvm-svn: 41477
Diffstat (limited to 'clang')
-rw-r--r--clang/Parse/ParseStmt.cpp3
-rw-r--r--clang/Sema/SemaStmt.cpp26
-rw-r--r--clang/include/clang/Basic/DiagnosticKinds.def3
-rw-r--r--clang/test/Sema/c89.c19
4 files changed, 43 insertions, 8 deletions
diff --git a/clang/Parse/ParseStmt.cpp b/clang/Parse/ParseStmt.cpp
index cae056aa8eb..80f7f0329e1 100644
--- a/clang/Parse/ParseStmt.cpp
+++ b/clang/Parse/ParseStmt.cpp
@@ -84,7 +84,6 @@ Parser::StmtResult Parser::ParseStatementOrDeclaration(bool OnlyStatement) {
default:
if (!OnlyStatement && isDeclarationSpecifier()) {
- // TODO: warn/disable if declaration is in the middle of a block and !C99.
return Actions.ParseDeclStmt(ParseDeclaration(Declarator::BlockContext));
} else if (Tok.getKind() == tok::r_brace) {
Diag(Tok, diag::err_expected_statement);
@@ -305,7 +304,6 @@ Parser::StmtResult Parser::ParseCaseStatement() {
if (SubStmt.isInvalid)
SubStmt = Actions.ParseNullStmt(ColonLoc);
- // TODO: look up enclosing switch stmt.
return Actions.ParseCaseStmt(CaseLoc, LHS.Val, DotDotDotLoc, RHSVal, ColonLoc,
SubStmt.Val);
}
@@ -337,7 +335,6 @@ Parser::StmtResult Parser::ParseDefaultStatement() {
if (SubStmt.isInvalid)
return true;
- // TODO: look up enclosing switch stmt.
return Actions.ParseDefaultStmt(DefaultLoc, ColonLoc, SubStmt.Val, CurScope);
}
diff --git a/clang/Sema/SemaStmt.cpp b/clang/Sema/SemaStmt.cpp
index 0bd05d86aed..f4c54147778 100644
--- a/clang/Sema/SemaStmt.cpp
+++ b/clang/Sema/SemaStmt.cpp
@@ -47,12 +47,28 @@ Sema::StmtResult Sema::ParseDeclStmt(DeclTy *decl) {
Action::StmtResult
Sema::ParseCompoundStmt(SourceLocation L, SourceLocation R,
- StmtTy **Elts, unsigned NumElts) {
- // FIXME: ISO C90 forbids mixed declarations and code
- // Note that __extension__ can be around a decl.
-
+ StmtTy **elts, unsigned NumElts) {
+ Stmt **Elts = reinterpret_cast<Stmt**>(elts);
+ // If we're in C89 mode, check that we don't have any decls after stmts. If
+ // so, emit an extension diagnostic.
+ if (!getLangOptions().C99 && !getLangOptions().CPlusPlus) {
+ // Note that __extension__ can be around a decl.
+ unsigned i = 0;
+ // Skip over all declarations.
+ for (; i != NumElts && isa<DeclStmt>(Elts[i]); ++i)
+ /*empty*/;
+
+ // We found the end of the list or a statement. Scan for another declstmt.
+ for (; i != NumElts && !isa<DeclStmt>(Elts[i]); ++i)
+ /*empty*/;
+
+ if (i != NumElts) {
+ Decl *D = cast<DeclStmt>(Elts[i])->getDecl();
+ Diag(D->getLocation(), diag::ext_mixed_decls_code);
+ }
+ }
- return new CompoundStmt((Stmt**)Elts, NumElts);
+ return new CompoundStmt(Elts, NumElts);
}
Action::StmtResult
diff --git a/clang/include/clang/Basic/DiagnosticKinds.def b/clang/include/clang/Basic/DiagnosticKinds.def
index 721a6a5781f..67148549725 100644
--- a/clang/include/clang/Basic/DiagnosticKinds.def
+++ b/clang/include/clang/Basic/DiagnosticKinds.def
@@ -279,6 +279,9 @@ DIAG(ext_integer_increment_complex, EXTENSION,
"ISO C does not support '++'/'--' on complex integer types")
DIAG(ext_integer_complement_complex, EXTENSION,
"ISO C does not support '~' for complex conjugation")
+
+DIAG(ext_mixed_decls_code, EXTENSION,
+ "ISO C90 forbids mixing declarations and code")
DIAG(ext_empty_struct_union_enum, EXTENSION,
"use of empty %0 extension")
diff --git a/clang/test/Sema/c89.c b/clang/test/Sema/c89.c
new file mode 100644
index 00000000000..57085db6446
--- /dev/null
+++ b/clang/test/Sema/c89.c
@@ -0,0 +1,19 @@
+/* RUN: clang %s -std=c89 -pedantic -parse-ast-check
+ */
+void foo() {
+ {
+ int i;
+ i = i + 1;
+ int j; /* expected-warning {{mixing declarations and code}} */
+ }
+ {
+ __extension__ int i;
+ i = i + 1;
+ int j; /* expected-warning {{mixing declarations and code}} */
+ }
+ {
+ int i;
+ i = i + 1;
+ __extension__ int j; /* expected-warning {{mixing declarations and code}} */
+ }
+}
OpenPOWER on IntegriCloud