[clang] [Clang] Fix crash with `source_location` in lambda declarators. (PR #107411)

via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 5 08:20:24 PDT 2024


https://github.com/cor3ntin updated https://github.com/llvm/llvm-project/pull/107411

>From b559fc6d23f78f6ac4069d0fd29cab18e194a50b Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Thu, 5 Sep 2024 16:36:10 +0200
Subject: [PATCH 1/2] [Clang] Fix crash with `source_location` in lambda
 declarators.

Parsing lambdas require pushing a declaration context for the lambda,
so that parameters can be attached to it, before its trailing type is parsed.
DAt that point, partially-parsed lambda don't have a name that can be computed
for then.
This would cause source_location::current() to crash when use in the decltype
of a lambda().
We work around this by producing a source_location for an enclosing scope
in that scenario.

Fixes #67134
---
 clang/docs/ReleaseNotes.rst            |  1 +
 clang/lib/AST/Expr.cpp                 | 10 ++++++++++
 clang/test/SemaCXX/source_location.cpp | 13 +++++++++++++
 3 files changed, 24 insertions(+)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index ab3c3e6049f602..968283a73a7f81 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -366,6 +366,7 @@ Bug Fixes to C++ Support
 - Clang no longer tries to capture non-odr used default arguments of template parameters of generic lambdas (#GH107048)
 - Fixed a bug where defaulted comparison operators would remove ``const`` from base classes. (#GH102588)
 
+- Fix a crash when using ``source_location`` in the trailing return type of a lambda expression. (#GH67134)
 
 Bug Fixes to AST Handling
 ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 96c6276f3f34c1..27930db019a172 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -13,6 +13,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/APValue.h"
 #include "clang/AST/ASTContext.h"
+#include "clang/AST/ASTLambda.h"
 #include "clang/AST/Attr.h"
 #include "clang/AST/ComputeDependence.h"
 #include "clang/AST/DeclCXX.h"
@@ -2287,6 +2288,15 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx,
     Context = getParentContext();
   }
 
+  // If we are currently parsing a lambda declarator, we might not have a fully
+  // formed call operator declaration yet, and we could not form a function name
+  // for it. Because we do not have access to Sema/function scopes here, we
+  // detect this case by relying on the fact such method doesn't yet have a
+  // type.
+  if (const auto *D = dyn_cast<CXXMethodDecl>(Context);
+      D && D->getFunctionTypeLoc().isNull() && isLambdaCallOperator(D))
+    Context = D->getParent()->getParent();
+
   PresumedLoc PLoc = Ctx.getSourceManager().getPresumedLoc(
       Ctx.getSourceManager().getExpansionRange(Loc).getEnd());
 
diff --git a/clang/test/SemaCXX/source_location.cpp b/clang/test/SemaCXX/source_location.cpp
index 34177bfe287fc3..60aa19ae995674 100644
--- a/clang/test/SemaCXX/source_location.cpp
+++ b/clang/test/SemaCXX/source_location.cpp
@@ -989,3 +989,16 @@ void Test() {
 }
 
 #endif
+
+
+namespace GH67134 {
+template <int loc = std::source_location::current().line()>
+constexpr auto f(std::source_location loc2 = std::source_location::current()) { return loc; }
+int g = []() -> decltype(f()) { return 0; }();
+int call() {
+#if __cplusplus >= 202002L
+  return []<decltype(f()) = 0>() -> decltype(f()) { return  0; }();
+#endif
+  return []() -> decltype(f()) { return  0; }();
+}
+}

>From a0573511c495dff26d60e997ec5dee94e706ce5f Mon Sep 17 00:00:00 2001
From: Corentin Jabot <corentinjabot at gmail.com>
Date: Thu, 5 Sep 2024 17:20:10 +0200
Subject: [PATCH 2/2] add tests

---
 clang/test/SemaCXX/source_location.cpp | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/clang/test/SemaCXX/source_location.cpp b/clang/test/SemaCXX/source_location.cpp
index 60aa19ae995674..8b3a5d8dd3327d 100644
--- a/clang/test/SemaCXX/source_location.cpp
+++ b/clang/test/SemaCXX/source_location.cpp
@@ -994,11 +994,21 @@ void Test() {
 namespace GH67134 {
 template <int loc = std::source_location::current().line()>
 constexpr auto f(std::source_location loc2 = std::source_location::current()) { return loc; }
+
 int g = []() -> decltype(f()) { return 0; }();
+
 int call() {
 #if __cplusplus >= 202002L
   return []<decltype(f()) = 0>() -> decltype(f()) { return  0; }();
 #endif
   return []() -> decltype(f()) { return  0; }();
 }
+
+#if __cplusplus >= 202002L
+template<typename T>
+int Var = requires { []() -> decltype(f()){}; };
+int h = Var<int>;
+#endif
+
+
 }



More information about the cfe-commits mailing list