PR18128: a lambda capture-default is not permitted for a non-local lambda
expression. llvm-svn: 200948
This commit is contained in:
parent
3a4bf0405e
commit
3d584b0ced
|
@ -952,6 +952,8 @@ def err_capture_of_abstract_type : Error<
|
|||
"by-copy capture of value of abstract type %0">;
|
||||
def err_capture_of_incomplete_type : Error<
|
||||
"by-copy capture of variable %0 with incomplete type %1">;
|
||||
def err_capture_default_non_local : Error<
|
||||
"non-local lambda expression cannot have a capture-default">;
|
||||
|
||||
def err_multiple_final_overriders : Error<
|
||||
"virtual function %q0 has more than one final overrider in %1">;
|
||||
|
|
|
@ -256,7 +256,7 @@ CXXRecordDecl *Sema::createLambdaClosureType(SourceRange IntroducerRange,
|
|||
IsGenericLambda,
|
||||
CaptureDefault);
|
||||
DC->addDecl(Class);
|
||||
|
||||
|
||||
return Class;
|
||||
}
|
||||
|
||||
|
@ -935,6 +935,23 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro,
|
|||
ExplicitResultType,
|
||||
!Method->isConst());
|
||||
|
||||
// C++11 [expr.prim.lambda]p9:
|
||||
// A lambda-expression whose smallest enclosing scope is a block scope is a
|
||||
// local lambda expression; any other lambda expression shall not have a
|
||||
// capture-default or simple-capture in its lambda-introducer.
|
||||
//
|
||||
// For simple-captures, this is covered by the check below that any named
|
||||
// entity is a variable that can be captured.
|
||||
//
|
||||
// For DR1632, we also allow a capture-default in any context where we can
|
||||
// odr-use 'this' (in particular, in a default initializer for a non-static
|
||||
// data member).
|
||||
if (Intro.Default != LCD_None && !Class->getParent()->isFunctionOrMethod() &&
|
||||
(getCurrentThisType().isNull() ||
|
||||
CheckCXXThisCapture(SourceLocation(), /*Explicit*/true,
|
||||
/*BuildAndDiagnose*/false)))
|
||||
Diag(Intro.DefaultLoc, diag::err_capture_default_non_local);
|
||||
|
||||
// Distinct capture names, for diagnostics.
|
||||
llvm::SmallSet<IdentifierInfo*, 8> CaptureNames;
|
||||
|
||||
|
|
|
@ -291,7 +291,7 @@ namespace NSDMIs_in_lambdas {
|
|||
void f() { []() { S<int> s; }; }
|
||||
|
||||
auto x = []{ struct S { int n, m = n; }; };
|
||||
auto y = [&]{ struct S { int n, m = n; }; };
|
||||
auto y = [&]{ struct S { int n, m = n; }; }; // expected-error {{non-local lambda expression cannot have a capture-default}}
|
||||
void g() { auto z = [&]{ struct S { int n, m = n; }; }; }
|
||||
}
|
||||
|
||||
|
@ -324,3 +324,23 @@ namespace CaptureAbstract {
|
|||
[=] { return s.n; }; // expected-error {{abstract}}
|
||||
}
|
||||
}
|
||||
|
||||
namespace PR18128 {
|
||||
auto l = [=]{}; // expected-error {{non-local lambda expression cannot have a capture-default}}
|
||||
|
||||
struct S {
|
||||
int n;
|
||||
int (*f())[true ? 1 : ([=]{ return n; }(), 0)];
|
||||
// expected-error@-1 {{non-local lambda expression cannot have a capture-default}}
|
||||
// expected-error@-2 {{invalid use of non-static data member 'n'}}
|
||||
// expected-error@-3 {{a lambda expression may not appear inside of a constant expression}}
|
||||
int g(int k = ([=]{ return n; }(), 0));
|
||||
// expected-error@-1 {{non-local lambda expression cannot have a capture-default}}
|
||||
// expected-error@-2 {{invalid use of non-static data member 'n'}}
|
||||
|
||||
int a = [=]{ return n; }(); // ok
|
||||
int b = [=]{ return [=]{ return n; }(); }(); // ok
|
||||
int c = []{ int k = 0; return [=]{ return k; }(); }(); // ok
|
||||
int d = []{ return [=]{ return n; }(); }(); // expected-error {{'this' cannot be implicitly captured in this context}}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -1000,7 +1000,7 @@ TEST(Matcher, Call) {
|
|||
}
|
||||
|
||||
TEST(Matcher, Lambda) {
|
||||
EXPECT_TRUE(matches("auto f = [&] (int i) { return i; };",
|
||||
EXPECT_TRUE(matches("auto f = [] (int i) { return i; };",
|
||||
lambdaExpr()));
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue