Author: cor3ntin Date: 2024-01-18T07:17:45+01:00 New Revision: 8c2b0d4175dcfe669a43d0173fd00ed3c16dbdaa
URL: https://github.com/llvm/llvm-project/commit/8c2b0d4175dcfe669a43d0173fd00ed3c16dbdaa DIFF: https://github.com/llvm/llvm-project/commit/8c2b0d4175dcfe669a43d0173fd00ed3c16dbdaa.diff LOG: [Clang] Fix dependency of SourceLocExpr. (#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 Added: Modified: clang/docs/ReleaseNotes.rst clang/include/clang/AST/Expr.h clang/lib/AST/Expr.cpp clang/lib/Sema/TreeTransform.h clang/test/SemaCXX/source_location.cpp Removed: ################################################################################ diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index cf52c1e66b91b42..0ea6f93a1f5df9d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -972,6 +972,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 a function template. + 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 53e4544888ff668..9de3e356094670b 100644 --- a/clang/include/clang/AST/Expr.h +++ b/clang/include/clang/AST/Expr.h @@ -4756,6 +4756,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 b125fc676da8419..ade403da65dd959 100644 --- a/clang/lib/AST/Expr.cpp +++ b/clang/lib/AST/Expr.cpp @@ -2219,7 +2219,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 1a1bc87d2b3203c..4463904b07211bd 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 e92fb35b653a8f3..7414fbce7828d15 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