[clang] 8c2b0d4 - [Clang] Fix dependency of SourceLocExpr. (#78436)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Jan 17 22:17:50 PST 2024
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>();
+}
+
+}
More information about the cfe-commits
mailing list