Author: cor3ntin Date: 2024-09-05T20:45:31+02:00 New Revision: d219c63b16851ba264b6495e3f63016d1c8b2aac
URL: https://github.com/llvm/llvm-project/commit/d219c63b16851ba264b6495e3f63016d1c8b2aac DIFF: https://github.com/llvm/llvm-project/commit/d219c63b16851ba264b6495e3f63016d1c8b2aac.diff LOG: [Clang] Fix crash with `source_location` in lambda declarators. (#107411) 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 Added: Modified: clang/docs/ReleaseNotes.rst clang/lib/AST/Expr.cpp clang/test/SemaCXX/source_location.cpp Removed: ################################################################################ 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<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..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 <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 + + +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits