forked from OSchip/llvm-project
Two minor, related fixes for template instantiation with blocks:
- 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>. llvm-svn: 151372
This commit is contained in:
parent
dd5a59baed
commit
3a08c1cd3b
|
@ -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) {}
|
||||
|
||||
|
|
|
@ -7038,8 +7038,11 @@ 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
|
||||
|
||||
|
|
|
@ -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>();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue