https://github.com/ziqingluo-90 created 
https://github.com/llvm/llvm-project/pull/174253

A downstream test recovers a false negative introduced in #173096, where it 
changed the use of variable `FmtArgIdx` to `FmtArgStartingIdx`.  The two 
variables are different in that `FmtArgIdx` refers to the index of the format 
string and `FmtArgStartingIdx` refers to the index of the first format 
argument. The consequence is that the analysis will miss reporting an unsafe 
format string.

This fix also upstreams the test catching the FN.

>From 77806a31107a00ee23d90b6646f5c2ddd71c60a1 Mon Sep 17 00:00:00 2001
From: Ziqing Luo <[email protected]>
Date: Fri, 2 Jan 2026 15:47:00 -0800
Subject: [PATCH] [-Wunsafe-buffer-usage] Fix a false negative introduced in
 #173096

A downstream test recovers a false negative introduced in #173096,
where it changed the use of variable `FmtArgIdx` to
`FmtArgStartingIdx`.  The two variables are different in that
`FmtArgIdx` refers to the index of the format string and
`FmtArgStartingIdx` refers to the index of the first format
argument. The consequence is that the analysis will miss reporting an
unsafe format string.

This fix also upstreams the test catching the FN.
---
 clang/lib/Analysis/UnsafeBufferUsage.cpp                       | 2 +-
 clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp | 2 ++
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp 
b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 620da756c3a9c..245418aa5d4ea 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -954,7 +954,7 @@ hasUnsafeFormatOrSArg(ASTContext &Ctx, const CallExpr *Call,
   // In this case, this call is considered unsafe if at least one argument
   // (including the format argument) is unsafe pointer.
   return llvm::any_of(
-      llvm::make_range(Call->arg_begin() + FmtArgStartingIdx, Call->arg_end()),
+      llvm::make_range(Call->arg_begin() + FmtIdx, Call->arg_end()),
       [&UnsafeArg, &Ctx](const Expr *Arg) -> bool {
         if (Arg->getType()->isPointerType() && !isNullTermPointer(Arg, Ctx)) {
           UnsafeArg = Arg;
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp 
b/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp
index a68ecf128c3d9..facbb0eb995e9 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-libc-functions.cpp
@@ -108,6 +108,8 @@ void f(char * p, char * q, std::span<char> s, 
std::span<char> s2) {
   snprintf(q, 10, "%s%d", "hello", *p); // expected-warning{{function 
'snprintf' is unsafe}} expected-note{{buffer pointer and size may not match}}
   snprintf(cp, 10, "%s%d", "hello", *p); // expected-warning{{function 
'snprintf' is unsafe}} expected-note{{buffer pointer and size may not match}}
   snprintf(s.data(), s2.size(), "%s%d", "hello", *p); // 
expected-warning{{function 'snprintf' is unsafe}} expected-note{{buffer pointer 
and size may not match}}
+  printf(nullptr);                         // expected-warning{{function 
'printf' is unsafe}} expected-note{{string argument is not guaranteed to be 
null-terminated}}
+  printf("%s", nullptr);                   // expected-warning{{function 
'printf' is unsafe}} expected-note{{string argument is not guaranteed to be 
null-terminated}}
   snwprintf(s.data(), s2.size(), "%s%d", "hello", *p); // 
expected-warning{{function 'snwprintf' is unsafe}} expected-note{{buffer 
pointer and size may not match}}
   snwprintf_s(                      // expected-warning{{function 
'snwprintf_s' is unsafe}}
              s.data(),             // expected-note{{buffer pointer and size 
may not match}} // note attached to the buffer

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to