mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2025-01-15 12:39:19 +00:00
Don't instantiate lambda closure types in default member initializers
when instantiating the enclosing class. We'll build new lambda closure types if and when we instantiate the default member initializer, and instantiating the closure type by itself can go wrong in cases where we fully-instantiate nested classes (in explicit instantiations of the enclosing class and when the enclosing class is a local class) -- we will instantiate the 'operator()' as a regular function rather than as a lambda call operator, so it doesn't get to use its captures, has the wrong 'this' type, etc.
This commit is contained in:
parent
ebdcef20ce
commit
15e772e8dc
@ -2696,7 +2696,10 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation,
|
||||
|
||||
// BlockDecls can appear in a default-member-initializer. They must be the
|
||||
// child of a BlockExpr, so we only know how to instantiate them from there.
|
||||
if (isa<BlockDecl>(Member))
|
||||
// Similarly, lambda closure types are recreated when instantiating the
|
||||
// corresponding LambdaExpr.
|
||||
if (isa<BlockDecl>(Member) ||
|
||||
(isa<CXXRecordDecl>(Member) && cast<CXXRecordDecl>(Member)->isLambda()))
|
||||
continue;
|
||||
|
||||
if (Member->isInvalidDecl()) {
|
||||
|
@ -179,4 +179,10 @@ struct B : A<0> {
|
||||
virtual void foo() override; // expected-error{{declaration of 'foo' overrides a 'final' function}}
|
||||
};
|
||||
}
|
||||
|
||||
template<typename T> struct LambdaInDefaultMemberInitInExplicitInstantiation {
|
||||
int a = [this] { return a; }();
|
||||
};
|
||||
template struct LambdaInDefaultMemberInitInExplicitInstantiation<int>;
|
||||
LambdaInDefaultMemberInitInExplicitInstantiation<float> x;
|
||||
#endif
|
||||
|
@ -495,3 +495,12 @@ namespace PR45000 {
|
||||
void g() { f<int>(); }
|
||||
// expected-note@-1 {{in instantiation of default function argument expression for 'f<int>' required here}}
|
||||
}
|
||||
|
||||
namespace LambdaInDefaultMemberInitializer {
|
||||
template<typename T> void f() {
|
||||
struct S {
|
||||
void *p = [this] { return &p; }();
|
||||
};
|
||||
}
|
||||
template void f<int>();
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user