@@ -2008,6 +2008,51 @@ bool DiagTypeid(InterpState &S, CodePtr OpPC) {
20082008 return false ;
20092009}
20102010
2011+ bool arePotentiallyOverlappingStringLiterals (const Pointer &LHS,
2012+ const Pointer &RHS) {
2013+ unsigned LHSOffset = LHS.getIndex ();
2014+ unsigned RHSOffset = RHS.getIndex ();
2015+ unsigned LHSLength = (LHS.getNumElems () - 1 ) * LHS.elemSize ();
2016+ unsigned RHSLength = (RHS.getNumElems () - 1 ) * RHS.elemSize ();
2017+
2018+ StringRef LHSStr ((const char *)LHS.atIndex (0 ).getRawAddress (), LHSLength);
2019+ StringRef RHSStr ((const char *)RHS.atIndex (0 ).getRawAddress (), RHSLength);
2020+ int32_t IndexDiff = RHSOffset - LHSOffset;
2021+ if (IndexDiff < 0 ) {
2022+ if (static_cast <int32_t >(LHSLength) < -IndexDiff)
2023+ return false ;
2024+ LHSStr = LHSStr.drop_front (-IndexDiff);
2025+ } else {
2026+ if (static_cast <int32_t >(RHSLength) < IndexDiff)
2027+ return false ;
2028+ RHSStr = RHSStr.drop_front (IndexDiff);
2029+ }
2030+
2031+ unsigned ShorterCharWidth;
2032+ StringRef Shorter;
2033+ StringRef Longer;
2034+ if (LHSLength < RHSLength) {
2035+ ShorterCharWidth = LHS.elemSize ();
2036+ Shorter = LHSStr;
2037+ Longer = RHSStr;
2038+ } else {
2039+ ShorterCharWidth = RHS.elemSize ();
2040+ Shorter = RHSStr;
2041+ Longer = LHSStr;
2042+ }
2043+
2044+ // The null terminator isn't included in the string data, so check for it
2045+ // manually. If the longer string doesn't have a null terminator where the
2046+ // shorter string ends, they aren't potentially overlapping.
2047+ for (unsigned NullByte : llvm::seq (ShorterCharWidth)) {
2048+ if (Shorter.size () + NullByte >= Longer.size ())
2049+ break ;
2050+ if (Longer[Shorter.size () + NullByte])
2051+ return false ;
2052+ }
2053+ return Shorter == Longer.take_front (Shorter.size ());
2054+ }
2055+
20112056// https://github.com/llvm/llvm-project/issues/102513
20122057#if defined(_MSC_VER) && !defined(__clang__) && !defined(NDEBUG)
20132058#pragma optimize("", off)
0 commit comments