aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouglas Gregor <dgregor@apple.com>2011-06-05 05:04:23 +0000
committerDouglas Gregor <dgregor@apple.com>2011-06-05 05:04:23 +0000
commit6a576ab708d3aa7d40e5d867ab1de5d3cb507553 (patch)
treee24705b477baeabe35cc9b07963f2e8195d126f0
parent7fee4cded72e2e00956ea34172d9ecc420c3a39f (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.cpp1
-rw-r--r--lib/Sema/SemaStmt.cpp22
-rw-r--r--test/CodeGenObjCXX/block-in-template-inst.mm39
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);
+ }
+}