https://github.com/cor3ntin created https://github.com/llvm/llvm-project/pull/78436
SourceLocExpr that may produce a function name are marked dependent so that the non-instantiated name of a function does not get evaluated. In GH78128, the name('s size) is used as template argument to a `DeclRef` that is not otherwise dependent, and therefore cached and not transformed when the function is instantiated, leading to 2 different values existing at the same time for the same function. Fixes #78128 >From ec8e4ad567daa15ddef6c90380f5b6877009b354 Mon Sep 17 00:00:00 2001 From: Corentin Jabot <corentinja...@gmail.com> Date: Wed, 17 Jan 2024 13:26:01 +0100 Subject: [PATCH] [Clang] Fix dependency of SourceLocExpr. SourceLocExpr that may produce a function name are marked dependent so that the non-instantiated name of a function does not get evaluated. In GH78128, the name('s size) is used as template argument to a Declref that is not dependent, and therefore not transformed and cached when the function is instantiated, leading to 2 different values existing at the same time for the same function. Fixes #78128 --- clang/docs/ReleaseNotes.rst | 4 ++++ clang/include/clang/AST/Expr.h | 11 +++++++++++ clang/lib/AST/Expr.cpp | 5 ++++- clang/lib/Sema/TreeTransform.h | 2 +- clang/test/SemaCXX/source_location.cpp | 27 ++++++++++++++++++++++++++ 5 files changed, 47 insertions(+), 2 deletions(-) diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index 174392da17551e..a18596097ecd4d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -913,6 +913,10 @@ Bug Fixes to C++ Support (`#57410 <https://github.com/llvm/llvm-project/issues/57410>`_) and (`#76604 <https://github.com/llvm/llvm-project/issues/57410>`_) +- Fix a bug where clang would produce inconsistent values when + std::source_location::current was used in function templates. + Fixes (`#78128 <https://github.com/llvm/llvm-project/issues/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 a41f2d66b37b69..8bce87fa7a46eb 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 a90f92d07f86d2..11697a07b0e322 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 1a1bc87d2b3203..4463904b07211b 100644 --- a/clang/lib/Sema/TreeTransform.h +++ b/clang/lib/Sema/TreeTransform.h @@ -12148,7 +12148,7 @@ TreeTransform<Derived>::TransformCXXMemberCallExpr(CXXMemberCallExpr *E) { template <typename Derived> ExprResult TreeTransform<Derived>::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 e92fb35b653a8f..7414fbce7828d1 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<int N> +constexpr int f() { + return N; +} + +template<typename T> +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<int>(); +} + +} _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits