Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[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

Merged
merged 2 commits into from
May 2, 2025

Conversation

cor3ntin
Copy link
Contributor

@cor3ntin cor3ntin commented May 1, 2025

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

… 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
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:frontend Language frontend issues, e.g. anything involving "Sema" labels May 1, 2025
@llvmbot
Copy link
Member

llvmbot commented May 1, 2025

@llvm/pr-subscribers-clang

Author: cor3ntin (cor3ntin)

Changes

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


Full diff: https://github.com/llvm/llvm-project/pull/138121.diff

3 Files Affected:

  • (modified) clang/docs/ReleaseNotes.rst (+2)
  • (modified) clang/lib/AST/DeclCXX.cpp (+5-1)
  • (modified) clang/test/SemaCXX/lambda-unevaluated.cpp (+16)
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;
Copy link
Collaborator

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.

Copy link
Contributor Author

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!

Copy link
Collaborator

@erichkeane erichkeane left a 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).

@cor3ntin cor3ntin merged commit aea2f6f into llvm:main May 2, 2025
12 checks passed
@cor3ntin cor3ntin deleted the gh138018 branch May 2, 2025 06:42
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
… 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
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
… 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
IanWood1 pushed a commit to IanWood1/llvm-project that referenced this pull request May 6, 2025
… 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
GeorgeARM pushed a commit to GeorgeARM/llvm-project that referenced this pull request May 7, 2025
… 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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:frontend Language frontend issues, e.g. anything involving "Sema" clang Clang issues not falling into any other category
Projects
None yet
4 participants