- Make sure that the block expression is instantiation-dependent if the
block is in a dependent context
- Make sure that the C++ 'this' expression gets captured even if we
don't rebuild the AST node during template instantiation. This would
also have manifested as a bug for lambdas.
Fixes <rdar://problem/
10832617>.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151372
91177308-0d34-0410-b5e6-
96231b3b80d8
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) {}
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());
}
oldCapture));
assert(blockScope->CaptureMap.count(newCapture));
}
+ assert(oldBlock->capturesCXXThis() == blockScope->isCXXThisCaptured());
}
#endif
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>();
+}