Author: cor3ntin
Date: 2025-05-02T08:42:29+02:00
New Revision: aea2f6f69cd256d85a0d3986c0e72181bb5247ab

URL: 
https://github.com/llvm/llvm-project/commit/aea2f6f69cd256d85a0d3986c0e72181bb5247ab
DIFF: 
https://github.com/llvm/llvm-project/commit/aea2f6f69cd256d85a0d3986c0e72181bb5247ab.diff

LOG: [Clang] incorrect assertion when checking template template parameter of a 
lambda (#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 #136432
Fixes #137014
Fixes #138018

Added: 
    

Modified: 
    clang/docs/ReleaseNotes.rst
    clang/lib/AST/DeclCXX.cpp
    clang/test/SemaCXX/lambda-unevaluated.cpp

Removed: 
    


################################################################################
diff  --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 76e811653aa9b..95e0574562a2d 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -621,6 +621,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..a3b3478e4b26a 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!");
 
@@ -1750,6 +1754,7 @@ CXXMethodDecl *CXXRecordDecl::getLambdaCallOperator() 
const {
 
 CXXMethodDecl* CXXRecordDecl::getLambdaStaticInvoker() const {
   CXXMethodDecl *CallOp = getLambdaCallOperator();
+  assert(CallOp && "null call operator");
   CallingConv CC = CallOp->getType()->castAs<FunctionType>()->getCallConv();
   return getLambdaStaticInvoker(CC);
 }

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


        
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to