diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 174392da17551..1d66bb960c3e6 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -913,6 +913,10 @@ Bug Fixes to C++ Support (`#57410 `_) and (`#76604 `_) +- Fix a bug where clang would produce inconsistent values when + ``std::source_location::current()`` was used in a function template. + Fixes (`#78128 `_) + Bug Fixes to AST Handling ^^^^^^^^^^^^^^^^^^^^^^^^^ - Fixed an import failure of recursive friend class template. diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h index a41f2d66b37b6..8bce87fa7a46e 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -4806,6 +4806,17 @@ class SourceLocExpr final : public Expr { return T->getStmtClass() == SourceLocExprClass; } + static bool MayBeDependent(SourceLocIdentKind Kind) { + switch (Kind) { + case SourceLocIdentKind::Function: + case SourceLocIdentKind::FuncSig: + case SourceLocIdentKind::SourceLocStruct: + return true; + default: + return false; + } + } + private: friend class ASTStmtReader; }; diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp index a90f92d07f86d..11697a07b0e32 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -2282,7 +2282,10 @@ SourceLocExpr::SourceLocExpr(const ASTContext &Ctx, SourceLocIdentKind Kind, : Expr(SourceLocExprClass, ResultTy, VK_PRValue, OK_Ordinary), BuiltinLoc(BLoc), RParenLoc(RParenLoc), ParentContext(ParentContext) { SourceLocExprBits.Kind = llvm::to_underlying(Kind); - setDependence(ExprDependence::None); + // In dependent contexts, function names may change. + setDependence(MayBeDependent(Kind) && ParentContext->isDependentContext() + ? ExprDependence::Value + : ExprDependence::None); } StringRef SourceLocExpr::getBuiltinStr() const { diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h index 1a1bc87d2b320..4463904b07211 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -12148,7 +12148,7 @@ TreeTransform::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) { template ExprResult TreeTransform::TransformSourceLocExpr(SourceLocExpr *E) { - bool NeedRebuildFunc = E->getIdentKind() == SourceLocIdentKind::Function && + bool NeedRebuildFunc = SourceLocExpr::MayBeDependent(E->getIdentKind()) && getSema().CurContext != E->getParentContext(); if (!getDerived().AlwaysRebuild() && !NeedRebuildFunc) diff --git a/clang/test/SemaCXX/source_location.cpp b/clang/test/SemaCXX/source_location.cpp index e92fb35b653a8..7414fbce7828d 100644 --- a/clang/test/SemaCXX/source_location.cpp +++ b/clang/test/SemaCXX/source_location.cpp @@ -805,3 +805,30 @@ static_assert(S(0).j == S{0}.j); static_assert(S(0).j == S{0}.i); } #endif + +namespace GH78128 { + +template +constexpr int f() { + return N; +} + +template +void foo() { + constexpr auto* F1 = std::source_location::current().function(); + static_assert(__builtin_strlen(F1) == f<__builtin_strlen(F1)>()); + + constexpr auto* F2 = __builtin_FUNCTION(); + static_assert(__builtin_strlen(F2) == f<__builtin_strlen(F2)>()); + +#ifdef MS + constexpr auto* F3 = __builtin_FUNCSIG(); + static_assert(__builtin_strlen(F3) == f<__builtin_strlen(F3)>()); +#endif +} + +void test() { + foo(); +} + +}