diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index ebd0b7371e1bed..a2e91fd648cce2 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -369,6 +369,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(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..8b3a5d8dd3327d 100644 --- a/clang/test/SemaCXX/source_location.cpp +++ b/clang/test/SemaCXX/source_location.cpp @@ -989,3 +989,26 @@ void Test() { } #endif + + +namespace GH67134 { +template +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()) { return 0; }(); +#endif + return []() -> decltype(f()) { return 0; }(); +} + +#if __cplusplus >= 202002L +template +int Var = requires { []() -> decltype(f()){}; }; +int h = Var; +#endif + + +}