Allow block returns in C++ with the form
return <expression> ; in blocks with a 'void' result type, so long as <expression> has type 'void'. This follows the rules for C++ functions. llvm-svn: 132658
This commit is contained in:
parent
0aa91e0a66
commit
7f139d8103
|
@ -1617,13 +1617,17 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) {
|
|||
// compatibility to worry about here.
|
||||
ReturnStmt *Result = 0;
|
||||
if (CurBlock->ReturnType->isVoidType()) {
|
||||
if (RetValExp) {
|
||||
if (RetValExp && !RetValExp->isTypeDependent() &&
|
||||
(!getLangOptions().CPlusPlus || !RetValExp->getType()->isVoidType())) {
|
||||
Diag(ReturnLoc, diag::err_return_block_has_expr);
|
||||
RetValExp = 0;
|
||||
}
|
||||
Result = new (Context) ReturnStmt(ReturnLoc, RetValExp, 0);
|
||||
} else if (!RetValExp) {
|
||||
return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr));
|
||||
if (!CurBlock->ReturnType->isDependentType())
|
||||
return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr));
|
||||
|
||||
Result = new (Context) ReturnStmt(ReturnLoc, 0, 0);
|
||||
} else {
|
||||
const VarDecl *NRVOCandidate = 0;
|
||||
|
||||
|
|
|
@ -118,3 +118,29 @@ void f(int (^bl)(A* a)); // expected-note {{candidate function not viable: no kn
|
|||
void g() {
|
||||
f(^(B* b) { return 0; }); // expected-error {{no matching function for call to 'f'}}
|
||||
}
|
||||
|
||||
namespace DependentReturn {
|
||||
template<typename T>
|
||||
void f(T t) {
|
||||
(void)^(T u) {
|
||||
if (t != u)
|
||||
return t + u;
|
||||
else
|
||||
return;
|
||||
};
|
||||
|
||||
(void)^(T u) {
|
||||
if (t == u)
|
||||
return;
|
||||
else
|
||||
return t + u;
|
||||
};
|
||||
}
|
||||
|
||||
struct X { };
|
||||
void operator+(X, X);
|
||||
bool operator==(X, X);
|
||||
bool operator!=(X, X);
|
||||
|
||||
template void f<X>(X);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue