From 9af5500f3f132f9a2f9abbe82113a7c7bb751472 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Fri, 27 Mar 2009 04:18:06 +0000 Subject: [PATCH] Fix rdar://6719156 - clang should emit a better error when blocks are disabled but are used anyway by changing blocks from being disabled in the parser to being disabled in Sema. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@67816 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/Basic/DiagnosticSemaKinds.td | 2 ++ lib/Parse/ParseDecl.cpp | 7 +++---- lib/Parse/ParseExpr.cpp | 20 ++++++++------------ lib/Parse/ParseTentative.cpp | 5 ++--- lib/Sema/SemaExpr.cpp | 4 ++++ lib/Sema/SemaType.cpp | 4 ++++ test/Sema/exprs.c | 8 +++++++- 7 files changed, 30 insertions(+), 20 deletions(-) diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index 5dbc3d0ce8..62647ff51c 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -1394,6 +1394,8 @@ def warn_stringcompare : Warning< // Blocks +def err_blocks_disable : Error<"blocks support disabled - compile with -fblocks" + " or pick a deployment target that supports them">; def err_expected_block_lbrace : Error<"expected '{' in block literal">; def err_goto_in_block : Error< "goto not allowed in block literal">; diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp index a9fbbbe498..2c26b13dc1 100644 --- a/lib/Parse/ParseDecl.cpp +++ b/lib/Parse/ParseDecl.cpp @@ -1682,11 +1682,10 @@ void Parser::ParseDeclaratorInternal(Declarator &D, tok::TokenKind Kind = Tok.getKind(); // Not a pointer, C++ reference, or block. - if (Kind != tok::star && + if (Kind != tok::star && Kind != tok::caret && (Kind != tok::amp || !getLang().CPlusPlus) && // We parse rvalue refs in C++03, because otherwise the errors are scary. - (Kind != tok::ampamp || !getLang().CPlusPlus) && - (Kind != tok::caret || !getLang().Blocks)) { + (Kind != tok::ampamp || !getLang().CPlusPlus)) { if (DirectDeclParser) (this->*DirectDeclParser)(D); return; @@ -1697,7 +1696,7 @@ void Parser::ParseDeclaratorInternal(Declarator &D, SourceLocation Loc = ConsumeToken(); // Eat the *, ^, & or &&. D.SetRangeEnd(Loc); - if (Kind == tok::star || (Kind == tok::caret && getLang().Blocks)) { + if (Kind == tok::star || Kind == tok::caret) { // Is a pointer. DeclSpec DS; diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index c0b28775ce..913f9baff1 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/lib/Parse/ParseExpr.cpp @@ -776,10 +776,7 @@ Parser::OwningExprResult Parser::ParseCastExpression(bool isUnaryExpression, return ParseObjCAtExpression(AtLoc); } case tok::caret: - if (getLang().Blocks) - return ParsePostfixExpressionSuffix(ParseBlockLiteralExpression()); - Diag(Tok, diag::err_expected_expression); - return ExprError(); + return ParsePostfixExpressionSuffix(ParseBlockLiteralExpression()); case tok::l_square: // These can be followed by postfix-expr pieces. if (getLang().ObjC1) @@ -1344,18 +1341,17 @@ Parser::OwningExprResult Parser::ParseBlockLiteralExpression() { OwningExprResult Result(Actions, true); - if (Tok.is(tok::l_brace)) { - OwningStmtResult Stmt(ParseCompoundStatementBody()); - if (!Stmt.isInvalid()) { - Result = Actions.ActOnBlockStmtExpr(CaretLoc, move(Stmt), CurScope); - } else { - Actions.ActOnBlockError(CaretLoc, CurScope); - } - } else { + if (!Tok.is(tok::l_brace)) { // Saw something like: ^expr Diag(Tok, diag::err_expected_expression); return ExprError(); } + + OwningStmtResult Stmt(ParseCompoundStatementBody()); + if (!Stmt.isInvalid()) + Result = Actions.ActOnBlockStmtExpr(CaretLoc, move(Stmt), CurScope); + else + Actions.ActOnBlockError(CaretLoc, CurScope); return move(Result); } diff --git a/lib/Parse/ParseTentative.cpp b/lib/Parse/ParseTentative.cpp index 176529ce9c..2cca2cdb1e 100644 --- a/lib/Parse/ParseTentative.cpp +++ b/lib/Parse/ParseTentative.cpp @@ -405,14 +405,13 @@ Parser::TPResult Parser::TryParseDeclarator(bool mayBeAbstract, if (Tok.is(tok::coloncolon) || Tok.is(tok::identifier)) TryAnnotateCXXScopeToken(); - if (Tok.is(tok::star) || Tok.is(tok::amp) || - (Tok.is(tok::caret) && getLang().Blocks) || + if (Tok.is(tok::star) || Tok.is(tok::amp) || Tok.is(tok::caret) || (Tok.is(tok::annot_cxxscope) && NextToken().is(tok::star))) { // ptr-operator ConsumeToken(); while (Tok.is(tok::kw_const) || Tok.is(tok::kw_volatile) || - Tok.is(tok::kw_restrict) ) + Tok.is(tok::kw_restrict)) ConsumeToken(); } else { break; diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 92a4de08e4..8922abd20b 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -4589,6 +4589,10 @@ void Sema::ActOnBlockError(SourceLocation CaretLoc, Scope *CurScope) { /// literal was successfully completed. ^(int x){...} Sema::OwningExprResult Sema::ActOnBlockStmtExpr(SourceLocation CaretLoc, StmtArg body, Scope *CurScope) { + // If blocks are disabled, emit an error. + if (!LangOpts.Blocks) + Diag(CaretLoc, diag::err_blocks_disable); + // Ensure that CurBlock is deleted. llvm::OwningPtr BSI(CurBlock); diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index f14eb65203..dbe19e3434 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -625,6 +625,10 @@ QualType Sema::GetTypeForDeclarator(Declarator &D, Scope *S, unsigned Skip) { switch (DeclType.Kind) { default: assert(0 && "Unknown decltype!"); case DeclaratorChunk::BlockPointer: + // If blocks are disabled, emit an error. + if (!LangOpts.Blocks) + Diag(DeclType.Loc, diag::err_blocks_disable); + if (DeclType.Cls.TypeQuals) Diag(D.getIdentifierLoc(), diag::err_qualified_block_pointer_type); if (!T.getTypePtr()->isFunctionType()) diff --git a/test/Sema/exprs.c b/test/Sema/exprs.c index d348d9e190..80334078f1 100644 --- a/test/Sema/exprs.c +++ b/test/Sema/exprs.c @@ -1,4 +1,4 @@ -// RUN: clang-cc %s -verify -pedantic -fsyntax-only +// RUN: clang-cc %s -verify -pedantic -fsyntax-only -fno-blocks // PR1966 _Complex double test1() { @@ -85,3 +85,9 @@ int test12(const char *X) { return X == "foo"; // expected-warning {{comparison against a string literal is unspecified}} } +// rdar://6719156 +void test13( + void (^P)()) { // expected-error {{blocks support disabled - compile with -fblocks}} + P(); + P = ^(){}; // expected-error {{blocks support disabled - compile with -fblocks}} +} -- 2.40.0