-
Notifications
You must be signed in to change notification settings - Fork 13.4k
[Clang] incorrect assertion when checking template template parameter of a lambda #138121
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
… of a lambda. When a lamdbda is used in an alias declaration, we were trying to refer to its call operator. However, that could happen before (or during) the call operator is defined. So we should not assume a lambda always has a call operator. Fixes llvm#136432 Fixes llvm#137014 Fixes llvm#138018
@llvm/pr-subscribers-clang Author: cor3ntin (cor3ntin) ChangesWhen a lambda is used in an alias declaration, we were trying to refer to its call operator. However, that could happen before (or during) the call operator is defined. So we should not assume a lambda always has a call operator. Fixes #136432 Full diff: https://github.com/llvm/llvm-project/pull/138121.diff 3 Files Affected:
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index f5cd1fbeabcfe..8a463f9aca0c9 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -529,6 +529,8 @@ Bug Fixes to C++ Support
- Clang now issues an error when placement new is used to modify a const-qualified variable
in a ``constexpr`` function. (#GH131432)
- Clang now emits a warning when class template argument deduction for alias templates is used in C++17. (#GH133806)
+- Fix a crash when checking the template template parameters of a dependent lambda appearing in an alias declaration.
+ (#GH136432), (#GH137014), (#GH138018)
Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index 4d07efd58f518..9095575ee1175 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -1696,7 +1696,11 @@ static NamedDecl* getLambdaCallOperatorHelper(const CXXRecordDecl &RD) {
RD.getASTContext().DeclarationNames.getCXXOperatorName(OO_Call);
DeclContext::lookup_result Calls = RD.lookup(Name);
- assert(!Calls.empty() && "Missing lambda call operator!");
+
+ // This can happen while building the lambda.
+ if (Calls.empty())
+ return nullptr;
+
assert(allLookupResultsAreTheSame(Calls) &&
"More than one lambda call operator!");
diff --git a/clang/test/SemaCXX/lambda-unevaluated.cpp b/clang/test/SemaCXX/lambda-unevaluated.cpp
index a9bcab58464e2..40f8a729fd912 100644
--- a/clang/test/SemaCXX/lambda-unevaluated.cpp
+++ b/clang/test/SemaCXX/lambda-unevaluated.cpp
@@ -266,3 +266,19 @@ void func() {
}
} // namespace GH88081
+
+namespace GH138018 {
+
+template <typename T> struct vec {};
+
+auto structure_to_typelist(auto) {
+ return []<template <typename> typename T>(T<int>) {
+ return 0;
+ }(vec<int>{});
+}
+
+template <typename T> using helper = decltype(structure_to_typelist(T{}));
+static_assert(__is_same_as(int, helper<int>));
+
+
+} // namespace GH138018
|
|
||
// This can happen while building the lambda. | ||
if (Calls.empty()) | ||
return nullptr; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I'm REALLY concerned about this. I don't think it is wrong, but just that we need to make sure we handle this value correctly. At least getLambdaStaticInvoker
doesn't handle the nullptr
correctly (though I guess the other two uses DO, so thats fine).
I wouldn't mind a bit of an audit to make sure that uses of getLambdaStaticInvoker
(and perhaps the others, but as they already acknowledged they could return null, i'm mildly less concerned) do a reasonable thing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I added an assert, which hinges on the fact that we don't look at the static invoker in cases where the lambda is incomplete.
I agree that having these various states in lambdas is a bit unfortunate, but it is a consequence of P2036.
If you have a better solution, I'm all ears!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm concerned about the static-invoker ending up just being an assert, but I guess that is no behavioral change (just 1 assert to another).
… of a lambda (llvm#138121) When a lambda is used in an alias declaration, we were trying to refer to its call operator. However, that could happen before (or during) the call operator is defined. So we should not assume a lambda always has a call operator. Fixes llvm#136432 Fixes llvm#137014 Fixes llvm#138018
… of a lambda (llvm#138121) When a lambda is used in an alias declaration, we were trying to refer to its call operator. However, that could happen before (or during) the call operator is defined. So we should not assume a lambda always has a call operator. Fixes llvm#136432 Fixes llvm#137014 Fixes llvm#138018
… of a lambda (llvm#138121) When a lambda is used in an alias declaration, we were trying to refer to its call operator. However, that could happen before (or during) the call operator is defined. So we should not assume a lambda always has a call operator. Fixes llvm#136432 Fixes llvm#137014 Fixes llvm#138018
… of a lambda (llvm#138121) When a lambda is used in an alias declaration, we were trying to refer to its call operator. However, that could happen before (or during) the call operator is defined. So we should not assume a lambda always has a call operator. Fixes llvm#136432 Fixes llvm#137014 Fixes llvm#138018
When a lambda is used in an alias declaration, we were trying to refer to its call operator. However, that could happen before (or during) the call operator is defined.
So we should not assume a lambda always has a call operator.
Fixes #136432
Fixes #137014
Fixes #138018