forked from OSchip/llvm-project
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
This commit is contained in:
parent
53cce5c195
commit
56ed2eab9e
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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}}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue