Skip to content

Commit d219c63

Browse files
authored
[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
1 parent 92e75c0 commit d219c63

File tree

3 files changed

+34
-0
lines changed

3 files changed

+34
-0
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,7 @@ Bug Fixes to C++ Support
369369
- Clang no longer tries to capture non-odr used default arguments of template parameters of generic lambdas (#GH107048)
370370
- Fixed a bug where defaulted comparison operators would remove ``const`` from base classes. (#GH102588)
371371

372+
- Fix a crash when using ``source_location`` in the trailing return type of a lambda expression. (#GH67134)
372373

373374
Bug Fixes to AST Handling
374375
^^^^^^^^^^^^^^^^^^^^^^^^^

clang/lib/AST/Expr.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
#include "clang/AST/Expr.h"
1414
#include "clang/AST/APValue.h"
1515
#include "clang/AST/ASTContext.h"
16+
#include "clang/AST/ASTLambda.h"
1617
#include "clang/AST/Attr.h"
1718
#include "clang/AST/ComputeDependence.h"
1819
#include "clang/AST/DeclCXX.h"
@@ -2287,6 +2288,15 @@ APValue SourceLocExpr::EvaluateInContext(const ASTContext &Ctx,
22872288
Context = getParentContext();
22882289
}
22892290

2291+
// If we are currently parsing a lambda declarator, we might not have a fully
2292+
// formed call operator declaration yet, and we could not form a function name
2293+
// for it. Because we do not have access to Sema/function scopes here, we
2294+
// detect this case by relying on the fact such method doesn't yet have a
2295+
// type.
2296+
if (const auto *D = dyn_cast<CXXMethodDecl>(Context);
2297+
D && D->getFunctionTypeLoc().isNull() && isLambdaCallOperator(D))
2298+
Context = D->getParent()->getParent();
2299+
22902300
PresumedLoc PLoc = Ctx.getSourceManager().getPresumedLoc(
22912301
Ctx.getSourceManager().getExpansionRange(Loc).getEnd());
22922302

clang/test/SemaCXX/source_location.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,3 +989,26 @@ void Test() {
989989
}
990990

991991
#endif
992+
993+
994+
namespace GH67134 {
995+
template <int loc = std::source_location::current().line()>
996+
constexpr auto f(std::source_location loc2 = std::source_location::current()) { return loc; }
997+
998+
int g = []() -> decltype(f()) { return 0; }();
999+
1000+
int call() {
1001+
#if __cplusplus >= 202002L
1002+
return []<decltype(f()) = 0>() -> decltype(f()) { return 0; }();
1003+
#endif
1004+
return []() -> decltype(f()) { return 0; }();
1005+
}
1006+
1007+
#if __cplusplus >= 202002L
1008+
template<typename T>
1009+
int Var = requires { []() -> decltype(f()){}; };
1010+
int h = Var<int>;
1011+
#endif
1012+
1013+
1014+
}

0 commit comments

Comments
 (0)