aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td2
-rw-r--r--lib/Parse/ParseDecl.cpp7
-rw-r--r--lib/Parse/ParseExpr.cpp20
-rw-r--r--lib/Parse/ParseTentative.cpp5
-rw-r--r--lib/Sema/SemaExpr.cpp4
-rw-r--r--lib/Sema/SemaType.cpp4
-rw-r--r--test/Sema/exprs.c8
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<BlockSemaInfo> 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}}
+}