mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 22:00:10 +00:00
[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
This commit is contained in:
parent
9917d39dfc
commit
8c2b0d4175
@ -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.
|
||||
|
@ -4756,6 +4756,17 @@ public:
|
||||
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;
|
||||
};
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
|
@ -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>();
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user