From: Chris Lattner Date: Mon, 27 Aug 2007 04:29:41 +0000 (+0000) Subject: extwarn about decls intermixed with code in c89 mode. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=c30ebfbf23d6a471146e3c68c2cf7f170b7e55dc;p=clang extwarn about decls intermixed with code in c89 mode. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@41477 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Parse/ParseStmt.cpp b/Parse/ParseStmt.cpp index cae056aa8e..80f7f0329e 100644 --- a/Parse/ParseStmt.cpp +++ b/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/Sema/SemaStmt.cpp b/Sema/SemaStmt.cpp index 0bd05d86ae..f4c5414777 100644 --- a/Sema/SemaStmt.cpp +++ b/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(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(Elts[i]); ++i) + /*empty*/; + + // We found the end of the list or a statement. Scan for another declstmt. + for (; i != NumElts && !isa(Elts[i]); ++i) + /*empty*/; + + if (i != NumElts) { + Decl *D = cast(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/include/clang/Basic/DiagnosticKinds.def b/include/clang/Basic/DiagnosticKinds.def index 721a6a5781..6714854972 100644 --- a/include/clang/Basic/DiagnosticKinds.def +++ b/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/test/Sema/c89.c b/test/Sema/c89.c new file mode 100644 index 0000000000..57085db644 --- /dev/null +++ b/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}} */ + } +}