aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/Expr.h5
-rw-r--r--lib/Sema/TreeTransform.h8
-rw-r--r--test/CodeGenCXX/blocks.cpp15
3 files changed, 23 insertions, 5 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h
index b9c3220c0b..741b47e560 100644
--- a/include/clang/AST/Expr.h
+++ b/include/clang/AST/Expr.h
@@ -4220,9 +4220,8 @@ protected:
public:
BlockExpr(BlockDecl *BD, QualType ty)
: Expr(BlockExprClass, ty, VK_RValue, OK_Ordinary,
- ty->isDependentType(), false,
- // FIXME: Check for instantiate-dependence in the statement?
- ty->isInstantiationDependentType(),
+ ty->isDependentType(), ty->isDependentType(),
+ ty->isInstantiationDependentType() || BD->isDependentContext(),
false),
TheBlock(BD) {}
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index f0b5f4e241..11f03fc133 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -7038,9 +7038,12 @@ TreeTransform<Derived>::TransformCXXThisExpr(CXXThisExpr *E) {
T = getSema().Context.getPointerType(
getSema().Context.getRecordType(cast<CXXRecordDecl>(DC)));
- if (!getDerived().AlwaysRebuild() && T == E->getType())
+ if (!getDerived().AlwaysRebuild() && T == E->getType()) {
+ // Make sure that we capture 'this'.
+ getSema().CheckCXXThisCapture(E->getLocStart());
return SemaRef.Owned(E);
-
+ }
+
return getDerived().RebuildCXXThisExpr(E->getLocStart(), T, E->isImplicit());
}
@@ -8539,6 +8542,7 @@ TreeTransform<Derived>::TransformBlockExpr(BlockExpr *E) {
oldCapture));
assert(blockScope->CaptureMap.count(newCapture));
}
+ assert(oldBlock->capturesCXXThis() == blockScope->isCXXThisCaptured());
}
#endif
diff --git a/test/CodeGenCXX/blocks.cpp b/test/CodeGenCXX/blocks.cpp
index 3d7fcfddbe..eb544787da 100644
--- a/test/CodeGenCXX/blocks.cpp
+++ b/test/CodeGenCXX/blocks.cpp
@@ -211,3 +211,18 @@ namespace test7 {
return ^{ return *p; }();
}
}
+
+namespace test8 {
+ // <rdar://problem/10832617>: failure to capture this after skipping rebuild
+ // of the 'this' pointer.
+ struct X {
+ int x;
+
+ template<typename T>
+ int foo() {
+ return ^ { return x; }();
+ }
+ };
+
+ template int X::foo<int>();
+}