summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorMike Stump <mrs@apple.com>2009-04-29 21:40:37 +0000
committerMike Stump <mrs@apple.com>2009-04-29 21:40:37 +0000
commit56ed2eab9ece1540e6079c1b82a436f57a4d088f (patch)
tree447759bfd3f32b5b3746594d1850f56977e8b8a2 /clang
parent53cce5c195e1c1fb5cc0fc42d82374ae14b7f7d9 (diff)
downloadbcm5719-llvm-56ed2eab9ece1540e6079c1b82a436f57a4d088f.tar.gz
bcm5719-llvm-56ed2eab9ece1540e6079c1b82a436f57a4d088f.zip
Fixup Sema and CodeGen for block literal attributes when the return
type and argument types are missing, and let return type deduction happen before we give errors for returning from a noreturn block. Radar 6441502 llvm-svn: 70413
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/Parse/ParseExpr.cpp4
-rw-r--r--clang/lib/Sema/SemaExpr.cpp3
-rw-r--r--clang/lib/Sema/SemaStmt.cpp13
-rw-r--r--clang/test/Sema/block-return.c3
4 files changed, 14 insertions, 9 deletions
diff --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 1f37532d718..c0a0aad175c 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1291,6 +1291,10 @@ void Parser::ParseBlockId() {
Declarator DeclaratorInfo(DS, Declarator::BlockLiteralContext);
ParseDeclarator(DeclaratorInfo);
+ // We do this for: ^ __attribute__((noreturn)) {, as DS has the attributes.
+ DeclaratorInfo.AddAttributes(DS.TakeAttributes(),
+ SourceLocation());
+
if (Tok.is(tok::kw___attribute)) {
SourceLocation Loc;
AttributeList *AttrList = ParseAttributes(&Loc);
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 5d16d77f9f6..99ed741120e 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -4722,6 +4722,8 @@ void Sema::ActOnBlockStart(SourceLocation CaretLoc, Scope *BlockScope) {
void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
assert(ParamInfo.getIdentifier() == 0 && "block-id should have no identifier!");
+ ProcessDeclAttributes(CurBlock->TheDecl, ParamInfo);
+
if (ParamInfo.getNumTypeObjects() == 0
|| ParamInfo.getTypeObject(0).Kind != DeclaratorChunk::Function) {
QualType T = GetTypeForDeclarator(ParamInfo, CurScope);
@@ -4773,7 +4775,6 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) {
}
CurBlock->TheDecl->setParams(Context, &CurBlock->Params[0],
CurBlock->Params.size());
- ProcessDeclAttributes(CurBlock->TheDecl, ParamInfo);
for (BlockDecl::param_iterator AI = CurBlock->TheDecl->param_begin(),
E = CurBlock->TheDecl->param_end(); AI != E; ++AI)
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index e44aeb75575..fff7a44bc40 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -706,13 +706,6 @@ Sema::ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope) {
///
Action::OwningStmtResult
Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
-
- if (CurBlock->TheDecl->hasAttr<NoReturnAttr>()) {
- Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr)
- << getCurFunctionOrMethodDecl()->getDeclName();
- return StmtError();
- }
-
// If this is the first return we've seen in the block, infer the type of
// the block from it.
if (CurBlock->ReturnType == 0) {
@@ -726,6 +719,12 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
}
QualType FnRetType = QualType(CurBlock->ReturnType, 0);
+ if (CurBlock->TheDecl->hasAttr<NoReturnAttr>()) {
+ Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr)
+ << getCurFunctionOrMethodDecl()->getDeclName();
+ return StmtError();
+ }
+
// Otherwise, verify that this result type matches the previous one. We are
// pickier with blocks than for normal functions because we don't have GCC
// compatibility to worry about here.
diff --git a/clang/test/Sema/block-return.c b/clang/test/Sema/block-return.c
index 4a32a97a5de..e1a3cfd8123 100644
--- a/clang/test/Sema/block-return.c
+++ b/clang/test/Sema/block-return.c
@@ -97,7 +97,8 @@ int (*funcptr3[5])(long);
int sz8 = sizeof(^int (*[5])(long) {return funcptr3;}); // expected-error {{block declared as returning an array}}
void foo6() {
- void (^b)(int) __attribute__((noreturn));
+ int (^b)(int) __attribute__((noreturn));
b = ^ (int i) __attribute__((noreturn)) { return 1; }; // expected-error {{block declared 'noreturn' should not return}}
b(1);
+ int (^c)(void) __attribute__((noreturn)) = ^ __attribute__((noreturn)) { return 100; }; // expected-error {{block declared 'noreturn' should not return}}
}
OpenPOWER on IntegriCloud