diff options
-rw-r--r-- | clang/lib/AST/ExprConstant.cpp | 5 | ||||
-rw-r--r-- | clang/test/SemaCXX/lambda-expressions.cpp | 17 |
2 files changed, 17 insertions, 5 deletions
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp index df80cb4f944..7a17b76f05d 100644 --- a/clang/lib/AST/ExprConstant.cpp +++ b/clang/lib/AST/ExprConstant.cpp @@ -7861,6 +7861,11 @@ public: // either copied into the closure object's field that represents the '*this' // or refers to '*this'. if (isLambdaCallOperator(Info.CurrentCall->Callee)) { + // Ensure we actually have captured 'this'. (an error will have + // been previously reported if not). + if (!Info.CurrentCall->LambdaThisCaptureField) + return false; + // Update 'Result' to refer to the data member/field of the closure object // that represents the '*this' capture. if (!HandleLValueMember(Info, E, Result, diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp index 5fff855102f..0f4edc4d1f3 100644 --- a/clang/test/SemaCXX/lambda-expressions.cpp +++ b/clang/test/SemaCXX/lambda-expressions.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -std=c++14 -Wno-unused-value -fsyntax-only -verify -fblocks %s +// RUN: %clang_cc1 -std=c++14 -Wno-unused-value -fsyntax-only -verify -verify=expected-cxx14 -fblocks %s +// RUN: %clang_cc1 -std=c++17 -Wno-unused-value -fsyntax-only -verify -fblocks %s namespace std { class type_info; }; @@ -12,6 +13,7 @@ namespace ExplicitCapture { void ImplicitThisCapture() { [](){(void)Member;}; // expected-error {{'this' cannot be implicitly captured in this context}} + const int var = [](){(void)Member; return 0;}(); // expected-error {{'this' cannot be implicitly captured in this context}} [&](){(void)Member;}; [this](){(void)Member;}; @@ -105,7 +107,7 @@ namespace SpecialMembers { a = static_cast<decltype(a)&&>(a); // expected-error {{copy assignment operator is implicitly deleted}} } struct P { - P(const P&) = delete; // expected-note 2{{deleted here}} + P(const P&) = delete; //expected-note {{deleted here}} // expected-cxx14-note {{deleted here}} }; struct Q { ~Q() = delete; // expected-note {{deleted here}} @@ -118,8 +120,8 @@ namespace SpecialMembers { }; void g(P &p, Q &q, R &r) { // FIXME: The note attached to the second error here is just amazingly bad. - auto pp = [p]{}; // expected-error {{deleted constructor}} expected-error {{deleted copy constructor of '(lambda}} - // expected-note@-1 {{copy constructor of '' is implicitly deleted because field '' has a deleted copy constructor}} + auto pp = [p]{}; // expected-error {{deleted constructor}} expected-cxx14-error {{deleted copy constructor of '(lambda}} + // expected-cxx14-note@-1 {{copy constructor of '' is implicitly deleted because field '' has a deleted copy constructor}} auto qq = [q]{}; // expected-error {{deleted function}} expected-note {{because}} auto a = [r]{}; // expected-note 2{{here}} @@ -365,7 +367,7 @@ namespace PR18128 { 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}} + // expected-cxx14-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'}} @@ -596,8 +598,13 @@ namespace ConversionOperatorDoesNotHaveDeducedReturnType { using ExpectedTypeU = void (*)(T&); struct X { +#if __cplusplus > 201402L + friend constexpr auto T::operator()(int) const; + friend constexpr T::operator ExpectedTypeT() const noexcept; +#else friend auto T::operator()(int) const; friend T::operator ExpectedTypeT() const; +#endif // FIXME: The first of these should match. The second should not. template<typename T> |