Skip to content

Commit 563f86b

Browse files
committed
[clang] Fix crash when declaring invalid lambda member
1 parent 0fea00d commit 563f86b

File tree

2 files changed

+12
-11
lines changed

2 files changed

+12
-11
lines changed

clang/lib/AST/DeclCXX.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1526,10 +1526,9 @@ bool CXXRecordDecl::isGenericLambda() const {
15261526

15271527
#ifndef NDEBUG
15281528
static bool allLookupResultsAreTheSame(const DeclContext::lookup_result &R) {
1529-
for (auto *D : R)
1530-
if (!declaresSameEntity(D, R.front()))
1531-
return false;
1532-
return true;
1529+
return llvm::all_of(R, [&](NamedDecl *D) {
1530+
return D->isInvalidDecl() || declaresSameEntity(D, R.front());
1531+
});
15331532
}
15341533
#endif
15351534

clang/test/SemaCXX/lambda-expressions.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
// RUN: %clang_cc1 -std=c++11 -Wno-unused-value -fsyntax-only -verify=expected,expected-cxx14,cxx11 -fblocks %s
12
// RUN: %clang_cc1 -std=c++14 -Wno-unused-value -fsyntax-only -verify -verify=expected-cxx14 -fblocks %s
23
// RUN: %clang_cc1 -std=c++17 -Wno-unused-value -verify -ast-dump -fblocks %s | FileCheck %s
34

@@ -558,8 +559,8 @@ struct B {
558559
int x;
559560
A a = [&] { int y = x; };
560561
A b = [&] { [&] { [&] { int y = x; }; }; };
561-
A d = [&](auto param) { int y = x; };
562-
A e = [&](auto param) { [&] { [&](auto param2) { int y = x; }; }; };
562+
A d = [&](auto param) { int y = x; }; // cxx11-error {{'auto' not allowed in lambda parameter}}
563+
A e = [&](auto param) { [&] { [&](auto param2) { int y = x; }; }; }; // cxx11-error 2 {{'auto' not allowed in lambda parameter}}
563564
};
564565

565566
B<int> b;
@@ -589,6 +590,7 @@ struct S1 {
589590
void foo1() {
590591
auto s0 = S1{[name=]() {}}; // expected-error 2 {{expected expression}}
591592
auto s1 = S1{[name=name]() {}}; // expected-error {{use of undeclared identifier 'name'; did you mean 'name1'?}}
593+
// cxx11-warning@-1 {{initialized lambda captures are a C++14 extension}}
592594
}
593595
}
594596

@@ -604,7 +606,7 @@ namespace PR25627_dont_odr_use_local_consts {
604606

605607
namespace ConversionOperatorDoesNotHaveDeducedReturnType {
606608
auto x = [](int){};
607-
auto y = [](auto &v) -> void { v.n = 0; };
609+
auto y = [](auto &v) -> void { v.n = 0; }; // cxx11-error {{'auto' not allowed in lambda parameter}} cxx11-note {{candidate function not viable}} cxx11-note {{conversion candidate}}
608610
using T = decltype(x);
609611
using U = decltype(y);
610612
using ExpectedTypeT = void (*)(int);
@@ -624,22 +626,22 @@ namespace ConversionOperatorDoesNotHaveDeducedReturnType {
624626
template<typename T>
625627
friend constexpr U::operator ExpectedTypeU<T>() const noexcept;
626628
#else
627-
friend auto T::operator()(int) const;
629+
friend auto T::operator()(int) const; // cxx11-error {{'auto' return without trailing return type; deduced return types are a C++14 extension}}
628630
friend T::operator ExpectedTypeT() const;
629631

630632
template<typename T>
631-
friend void U::operator()(T&) const;
633+
friend void U::operator()(T&) const; // cxx11-error {{friend declaration of 'operator()' does not match any declaration}}
632634
// FIXME: This should not match, as above.
633635
template<typename T>
634-
friend U::operator ExpectedTypeU<T>() const;
636+
friend U::operator ExpectedTypeU<T>() const; // cxx11-error {{friend declaration of 'operator void (*)(type-parameter-0-0 &)' does not match any declaration}}
635637
#endif
636638

637639
private:
638640
int n;
639641
};
640642

641643
// Should be OK: lambda's call operator is a friend.
642-
void use(X &x) { y(x); }
644+
void use(X &x) { y(x); } // cxx11-error {{no matching function for call to object}}
643645

644646
// This used to crash in return type deduction for the conversion opreator.
645647
struct A { int n; void f() { +[](decltype(n)) {}; } };

0 commit comments

Comments
 (0)