================ @@ -2142,11 +2150,81 @@ static const ValueDecl *GetLValueBaseDecl(const LValue &LVal) { return LVal.Base.dyn_cast<const ValueDecl*>(); } -static bool IsLiteralLValue(const LValue &Value) { - if (Value.getLValueCallIndex()) +// Information about an LValueBase that is some kind of string. +struct LValueBaseString { + std::string ObjCEncodeStorage; + StringRef Bytes; + int CharWidth; +}; + +// Gets the lvalue base of LVal as a string. +static bool GetLValueBaseAsString(const EvalInfo &Info, const LValue &LVal, + LValueBaseString &AsString) { + const auto *BaseExpr = LVal.Base.dyn_cast<const Expr *>(); + if (!BaseExpr) + return false; + + // For ObjCEncodeExpr, we need to compute and store the string. + if (const auto *EE = dyn_cast<ObjCEncodeExpr>(BaseExpr)) { + Info.Ctx.getObjCEncodingForType(EE->getEncodedType(), + AsString.ObjCEncodeStorage); + AsString.Bytes = AsString.ObjCEncodeStorage; + AsString.CharWidth = 1; + return true; + } + + // Otherwise, we have a StringLiteral. + const auto *Lit = dyn_cast<StringLiteral>(BaseExpr); + if (const auto *PE = dyn_cast<PredefinedExpr>(BaseExpr)) + Lit = PE->getFunctionName(); + + if (!Lit) + return false; + + AsString.Bytes = Lit->getBytes(); + AsString.CharWidth = Lit->getCharByteWidth(); + return true; +} + +// Determine whether two string literals potentially overlap. This will be the +// case if they agree on the values of all the bytes on the overlapping region +// between them. +static bool ArePotentiallyOverlappingStringLiterals(const EvalInfo &Info, + const LValue &LHS, + const LValue &RHS) { + LValueBaseString LHSString, RHSString; + if (!GetLValueBaseAsString(Info, LHS, LHSString) || + !GetLValueBaseAsString(Info, RHS, RHSString)) return false; - const Expr *E = Value.Base.dyn_cast<const Expr*>(); - return E && !isa<MaterializeTemporaryExpr>(E); + + // This is the byte offset to the location of the first character of LHS + // within RHS. We don't need to look at the characters of one string that + // would appear before the start of the other string if they were merged. + CharUnits Offset = RHS.Offset - LHS.Offset; + if (Offset.isPositive()) { + RHSString.Bytes = RHSString.Bytes.drop_front(Offset.getQuantity()); + } else if (Offset.isNegative()) { + LHSString.Bytes = LHSString.Bytes.drop_front(-Offset.getQuantity()); + } ---------------- AaronBallman wrote:
```suggestion if (Offset.isPositive()) RHSString.Bytes = RHSString.Bytes.drop_front(Offset.getQuantity()); else if (Offset.isNegative()) LHSString.Bytes = LHSString.Bytes.drop_front(-Offset.getQuantity()); ``` https://github.com/llvm/llvm-project/pull/109208 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits