diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-06-05 05:04:23 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-06-05 05:04:23 +0000 |
commit | 6a576ab708d3aa7d40e5d867ab1de5d3cb507553 (patch) | |
tree | e24705b477baeabe35cc9b07963f2e8195d126f0 | |
parent | 7fee4cded72e2e00956ea34172d9ecc420c3a39f (diff) |
When inferring the result type of a block based on a return statement
with a type-dependent expression, infer the placeholder type
'Context.DependentTy' to indicate that this is just a
placeholder. Fixes PR9982 / <rdar://problem/9486685>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@132657 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/CodeGen/CodeGenModule.cpp | 1 | ||||
-rw-r--r-- | lib/Sema/SemaStmt.cpp | 22 | ||||
-rw-r--r-- | test/CodeGenObjCXX/block-in-template-inst.mm | 39 |
3 files changed, 52 insertions, 10 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index de11a29f67..bea70ea38f 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -2082,6 +2082,7 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { case Decl::FunctionTemplate: case Decl::TypeAliasTemplate: case Decl::NamespaceAlias: + case Decl::Block: break; case Decl::CXXConstructor: // Skip function templates diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp index ec0e74f0a7..1ecb4196b9 100644 --- a/lib/Sema/SemaStmt.cpp +++ b/lib/Sema/SemaStmt.cpp @@ -1589,14 +1589,18 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { if (Result.isInvalid()) return StmtError(); RetValExp = Result.take(); - CurBlock->ReturnType = RetValExp->getType(); - if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(RetValExp)) { - // We have to remove a 'const' added to copied-in variable which was - // part of the implementation spec. and not the actual qualifier for - // the variable. - if (CDRE->isConstQualAdded()) - CurBlock->ReturnType.removeLocalConst(); // FIXME: local??? - } + + if (!RetValExp->isTypeDependent()) { + CurBlock->ReturnType = RetValExp->getType(); + if (BlockDeclRefExpr *CDRE = dyn_cast<BlockDeclRefExpr>(RetValExp)) { + // We have to remove a 'const' added to copied-in variable which was + // part of the implementation spec. and not the actual qualifier for + // the variable. + if (CDRE->isConstQualAdded()) + CurBlock->ReturnType.removeLocalConst(); // FIXME: local??? + } + } else + CurBlock->ReturnType = Context.DependentTy; } else CurBlock->ReturnType = Context.VoidTy; } @@ -1658,7 +1662,7 @@ Sema::ActOnBlockReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp) { // If we need to check for the named return value optimization, save the // return statement in our scope for later processing. - if (getLangOptions().CPlusPlus && FnRetType->isRecordType() && + if (getLangOptions().CPlusPlus && FnRetType->isRecordType() && !CurContext->isDependentContext()) FunctionScopes.back()->Returns.push_back(Result); diff --git a/test/CodeGenObjCXX/block-in-template-inst.mm b/test/CodeGenObjCXX/block-in-template-inst.mm index 862488ddb7..72042fc033 100644 --- a/test/CodeGenObjCXX/block-in-template-inst.mm +++ b/test/CodeGenObjCXX/block-in-template-inst.mm @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm-only -fblocks -o - -triple x86_64-apple-darwin10 %s +// RUN: %clang_cc1 -emit-llvm-only -std=c++0x -fblocks -o - -triple x86_64-apple-darwin10 %s // rdar://9362021 @class DYFuture; @@ -32,3 +32,40 @@ void FUNC() ResourceManager<AnalyzerBaseObjectTypes> *rm; ^(void) { rm->XXX(); }(); } + +namespace PR9982 { + template<typename T> struct Curry; + + template<typename R, typename Arg0, typename Arg1, typename Arg2> + struct Curry<R (^)(Arg0, Arg1, Arg2)> + { + typedef R (^FType)(Arg0, Arg1, Arg2); + + Curry(FType _f) : f(_f) {} + ~Curry() {;} + + R (^(^operator()(Arg0 a))(Arg1))(Arg2) + { + auto block = ^(Arg1 b) { + auto inner_block = ^(Arg2 c) { + return f(a, b, c); + }; + return inner_block; + }; + return block; + } + + private: + FType f; + }; + + auto add = ^(int a, int b, int c) + { + return a + b + c; + }; + + void curry() { + Curry<__decltype(add)> c = Curry<__decltype(add)>(add); + auto t = c(1)(10)(100); + } +} |