From: Mike Stump Date: Wed, 29 Apr 2009 21:40:37 +0000 (+0000) Subject: Fixup Sema and CodeGen for block literal attributes when the return X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=6c92fa75e62937f9738696840efcb258560f4568;p=clang 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 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70413 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp index 1f37532d71..c0a0aad175 100644 --- a/lib/Parse/ParseExpr.cpp +++ b/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/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 5d16d77f9f..99ed741120 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/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/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index e44aeb7557..fff7a44bc4 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/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()) { - 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()) { + 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/test/Sema/block-return.c b/test/Sema/block-return.c index 4a32a97a5d..e1a3cfd812 100644 --- a/test/Sema/block-return.c +++ b/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}} }