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 | 0aa91e0a666003b7b48d80cd65146ba3cf752310 (patch) | |
tree | 0366615115e25740897ea157d50dbfd57208fbd9 | |
parent | 1134ab23dfa6a565888314f2ea52b33d3680bda0 (diff) | |
download | bcm5719-llvm-0aa91e0a666003b7b48d80cd65146ba3cf752310.tar.gz bcm5719-llvm-0aa91e0a666003b7b48d80cd65146ba3cf752310.zip |
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>.
llvm-svn: 132657
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaStmt.cpp | 22 | ||||
-rw-r--r-- | clang/test/CodeGenObjCXX/block-in-template-inst.mm | 39 |
3 files changed, 52 insertions, 10 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index de11a29f67b..bea70ea38f3 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/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/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp index ec0e74f0a7d..1ecb4196b9d 100644 --- a/clang/lib/Sema/SemaStmt.cpp +++ b/clang/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/clang/test/CodeGenObjCXX/block-in-template-inst.mm b/clang/test/CodeGenObjCXX/block-in-template-inst.mm index 862488ddb7e..72042fc0333 100644 --- a/clang/test/CodeGenObjCXX/block-in-template-inst.mm +++ b/clang/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); + } +} |