[clang] Reapply "[clang] Fix crash when declaring invalid lambda member" (PR #85427)
via cfe-commits
cfe-commits at lists.llvm.org
Fri Mar 15 09:50:03 PDT 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang
Author: Nikolas Klauser (philnik777)
<details>
<summary>Changes</summary>
This re-applies #<!-- -->74110 with the crashing code disabled in C++03. I'll
try to fix the new crash in it's own patch.
---
Full diff: https://github.com/llvm/llvm-project/pull/85427.diff
4 Files Affected:
- (modified) clang/docs/ReleaseNotes.rst (+3)
- (modified) clang/lib/AST/DeclCXX.cpp (+3-4)
- (modified) clang/test/SemaCXX/lambda-expressions.cpp (+13-8)
- (modified) llvm/lib/Support/CodeGenCoverage.cpp (+3)
``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index dfd88a128941ab..1e7243f62da381 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -300,6 +300,9 @@ Bug Fixes in This Version
by the C standard. This significantly improves codegen of `*` and `/` especially.
Fixes (`#31205 <https://github.com/llvm/llvm-project/issues/31205>`_).
+- Fixes an assertion failure on invalid code when trying to define member
+ functions in lambdas.
+
Bug Fixes to Compiler Builtins
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 1c3dcf63465c68..645ec2f7563bca 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -1567,10 +1567,9 @@ bool CXXRecordDecl::isGenericLambda() const {
#ifndef NDEBUG
static bool allLookupResultsAreTheSame(const DeclContext::lookup_result &R) {
- for (auto *D : R)
- if (!declaresSameEntity(D, R.front()))
- return false;
- return true;
+ return llvm::all_of(R, [&](NamedDecl *D) {
+ return D->isInvalidDecl() || declaresSameEntity(D, R.front());
+ });
}
#endif
diff --git a/clang/test/SemaCXX/lambda-expressions.cpp b/clang/test/SemaCXX/lambda-expressions.cpp
index 0516a5da31ae9a..389002ab0e349b 100644
--- a/clang/test/SemaCXX/lambda-expressions.cpp
+++ b/clang/test/SemaCXX/lambda-expressions.cpp
@@ -1,3 +1,4 @@
+// RUN: %clang_cc1 -std=c++11 -Wno-unused-value -fsyntax-only -verify=expected,expected-cxx14,cxx11 -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 -verify -ast-dump -fblocks %s | FileCheck %s
@@ -558,8 +559,8 @@ struct B {
int x;
A a = [&] { int y = x; };
A b = [&] { [&] { [&] { int y = x; }; }; };
- A d = [&](auto param) { int y = x; };
- A e = [&](auto param) { [&] { [&](auto param2) { int y = x; }; }; };
+ A d = [&](auto param) { int y = x; }; // cxx11-error {{'auto' not allowed in lambda parameter}}
+ A e = [&](auto param) { [&] { [&](auto param2) { int y = x; }; }; }; // cxx11-error 2 {{'auto' not allowed in lambda parameter}}
};
B<int> b;
@@ -589,6 +590,7 @@ struct S1 {
void foo1() {
auto s0 = S1{[name=]() {}}; // expected-error 2 {{expected expression}}
auto s1 = S1{[name=name]() {}}; // expected-error {{use of undeclared identifier 'name'; did you mean 'name1'?}}
+ // cxx11-warning at -1 {{initialized lambda captures are a C++14 extension}}
}
}
@@ -604,7 +606,7 @@ namespace PR25627_dont_odr_use_local_consts {
namespace ConversionOperatorDoesNotHaveDeducedReturnType {
auto x = [](int){};
- auto y = [](auto &v) -> void { v.n = 0; };
+ 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}}
using T = decltype(x);
using U = decltype(y);
using ExpectedTypeT = void (*)(int);
@@ -624,22 +626,22 @@ namespace ConversionOperatorDoesNotHaveDeducedReturnType {
template<typename T>
friend constexpr U::operator ExpectedTypeU<T>() const noexcept;
#else
- friend auto T::operator()(int) const;
+ friend auto T::operator()(int) const; // cxx11-error {{'auto' return without trailing return type; deduced return types are a C++14 extension}}
friend T::operator ExpectedTypeT() const;
template<typename T>
- friend void U::operator()(T&) const;
+ friend void U::operator()(T&) const; // cxx11-error {{friend declaration of 'operator()' does not match any declaration}}
// FIXME: This should not match, as above.
template<typename T>
- friend U::operator ExpectedTypeU<T>() const;
+ friend U::operator ExpectedTypeU<T>() const; // cxx11-error {{friend declaration of 'operator void (*)(type-parameter-0-0 &)' does not match any declaration}}
#endif
private:
int n;
};
- // Should be OK: lambda's call operator is a friend.
- void use(X &x) { y(x); }
+ // Should be OK in C++14 and later: lambda's call operator is a friend.
+ void use(X &x) { y(x); } // cxx11-error {{no matching function for call to object}}
// This used to crash in return type deduction for the conversion opreator.
struct A { int n; void f() { +[](decltype(n)) {}; } };
@@ -733,6 +735,8 @@ void GH67492() {
auto lambda = (test, []() noexcept(true) {});
}
+// FIXME: This currently causes clang to crash in C++11 mode.
+#if __cplusplus >= 201402L
namespace GH83267 {
auto l = [](auto a) { return 1; };
using type = decltype(l);
@@ -747,3 +751,4 @@ using t = decltype(ll);
template auto t::operator()<int>(int a) const; // expected-note {{in instantiation}}
}
+#endif
diff --git a/llvm/lib/Support/CodeGenCoverage.cpp b/llvm/lib/Support/CodeGenCoverage.cpp
index 0df45b4ff2ba75..61d15e118ce3a2 100644
--- a/llvm/lib/Support/CodeGenCoverage.cpp
+++ b/llvm/lib/Support/CodeGenCoverage.cpp
@@ -21,7 +21,10 @@
using namespace llvm;
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wglobal-constructors"
static sys::SmartMutex<true> OutputMutex;
+#pragma clang diagnostic pop
CodeGenCoverage::CodeGenCoverage() = default;
``````````
</details>
https://github.com/llvm/llvm-project/pull/85427
More information about the cfe-commits
mailing list