aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Interp.cpp
diff options
context:
space:
mode:
authorTimm Baeder <tbaeder@redhat.com>2025-06-03 16:26:31 +0200
committerGitHub <noreply@github.com>2025-06-03 16:26:31 +0200
commit2e70da3fba14f9ff0b29f65fed174f075d94d9a4 (patch)
treeb3d6e69b1cfc30930bc69980b354ff0073820dae /clang/lib/AST/ByteCode/Interp.cpp
parentd9df71045441e02d33cd01fad203862c7efd637e (diff)
downloadllvm-2e70da3fba14f9ff0b29f65fed174f075d94d9a4.zip
llvm-2e70da3fba14f9ff0b29f65fed174f075d94d9a4.tar.gz
llvm-2e70da3fba14f9ff0b29f65fed174f075d94d9a4.tar.bz2
[clang][bytecode] Partially address string literal uniqueness (#142555)
This still leaves the case of the constexpr auto b3 = name1() == name1(); test from cxx20.cpp broken.
Diffstat (limited to 'clang/lib/AST/ByteCode/Interp.cpp')
-rw-r--r--clang/lib/AST/ByteCode/Interp.cpp45
1 files changed, 45 insertions, 0 deletions
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 4d1e5c6..db91e5e 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -2008,6 +2008,51 @@ bool DiagTypeid(InterpState &S, CodePtr OpPC) {
return false;
}
+bool arePotentiallyOverlappingStringLiterals(const Pointer &LHS,
+ const Pointer &RHS) {
+ unsigned LHSOffset = LHS.getIndex();
+ unsigned RHSOffset = RHS.getIndex();
+ unsigned LHSLength = (LHS.getNumElems() - 1) * LHS.elemSize();
+ unsigned RHSLength = (RHS.getNumElems() - 1) * RHS.elemSize();
+
+ StringRef LHSStr((const char *)LHS.atIndex(0).getRawAddress(), LHSLength);
+ StringRef RHSStr((const char *)RHS.atIndex(0).getRawAddress(), RHSLength);
+ int32_t IndexDiff = RHSOffset - LHSOffset;
+ if (IndexDiff < 0) {
+ if (static_cast<int32_t>(LHSLength) < -IndexDiff)
+ return false;
+ LHSStr = LHSStr.drop_front(-IndexDiff);
+ } else {
+ if (static_cast<int32_t>(RHSLength) < IndexDiff)
+ return false;
+ RHSStr = RHSStr.drop_front(IndexDiff);
+ }
+
+ unsigned ShorterCharWidth;
+ StringRef Shorter;
+ StringRef Longer;
+ if (LHSLength < RHSLength) {
+ ShorterCharWidth = LHS.elemSize();
+ Shorter = LHSStr;
+ Longer = RHSStr;
+ } else {
+ ShorterCharWidth = RHS.elemSize();
+ Shorter = RHSStr;
+ Longer = LHSStr;
+ }
+
+ // The null terminator isn't included in the string data, so check for it
+ // manually. If the longer string doesn't have a null terminator where the
+ // shorter string ends, they aren't potentially overlapping.
+ for (unsigned NullByte : llvm::seq(ShorterCharWidth)) {
+ if (Shorter.size() + NullByte >= Longer.size())
+ break;
+ if (Longer[Shorter.size() + NullByte])
+ return false;
+ }
+ return Shorter == Longer.take_front(Shorter.size());
+}
+
// https://github.com/llvm/llvm-project/issues/102513
#if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG)
#pragma optimize("", off)