[clang] [Clang][UnsafeBufferUsage] Warn about two-arg string_view constructors. (PR #180471)
Rohan Jacob-Rao via cfe-commits
cfe-commits at lists.llvm.org
Fri Feb 13 14:35:23 PST 2026
================
@@ -699,6 +699,45 @@ static bool isSafeSpanTwoParamConstruct(const CXXConstructExpr &Node,
return isPtrBufferSafe(Arg0, Arg1, Ctx);
}
+static bool isSafeStringViewTwoParamConstruct(const CXXConstructExpr &Node,
+ ASTContext &Ctx) {
+ const Expr *Arg0 = Node.getArg(0)->IgnoreParenImpCasts();
+ const Expr *Arg1 = Node.getArg(1)->IgnoreParenImpCasts();
+
+ // Pattern 1: String Literals (Safe if size <= length)
+ if (const auto *SL = dyn_cast<StringLiteral>(Arg0)) {
+ if (auto ArgSize = Arg1->getIntegerConstantExpr(Ctx)) {
+ if (ArgSize->getZExtValue() <= SL->getLength())
+ return true;
+ }
+ }
+
+ // Pattern 2: Constant Arrays (Safe if exact match)
+ QualType T0 = Arg0->getType().getCanonicalType();
+ if (const auto *CAT = Ctx.getAsConstantArrayType(T0)) {
+ if (auto ArgSize = Arg1->getIntegerConstantExpr(Ctx)) {
+ // Wrap CAT->getSize() in APSInt to match ArgSize's type
+ if (llvm::APSInt::compareValues(llvm::APSInt(CAT->getSize(), /*isUnsigned=*/true),
+ *ArgSize) == 0)
+ return true;
+ }
+ }
+
+ // Pattern 3: Zero length is safe
+ if (auto Val = Arg1->getIntegerConstantExpr(Ctx)) {
+ if (Val->isZero()) return true;
+ }
+
+ // Pattern 4: Pointer/Iterator Pair
+ QualType T1 = Arg1->getType().getCanonicalType();
+ if ((T0->isPointerType() && T1->isPointerType()) ||
+ (T0->isRecordType() && T1->isRecordType())) {
----------------
rohanjr wrote:
I noticed that `isSafeSpanTwoParamConstruct()` doesn't allow the iterator range constructor in general, only calls with `x.begin()` and `x.end()`. Should we do the same here or do you have a reason to allow arbitrary pointers/iterators? I see in your test that we get a separate warning for unsafe pointer arithmetic, but that might not cover all unsafe cases.
https://github.com/llvm/llvm-project/pull/180471
More information about the cfe-commits
mailing list