[clang] da032a6 - [Wunsafe-buffer-usage] Fix false positives in handling string literals. (#115552)

via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 11 16:47:32 PST 2024


Author: Malavika Samak
Date: 2024-11-11T16:47:28-08:00
New Revision: da032a609c1bde6f6775cf1650e08a205920d920

URL: https://github.com/llvm/llvm-project/commit/da032a609c1bde6f6775cf1650e08a205920d920
DIFF: https://github.com/llvm/llvm-project/commit/da032a609c1bde6f6775cf1650e08a205920d920.diff

LOG: [Wunsafe-buffer-usage] Fix false positives in handling string literals. (#115552)

Do not warn when a string literal is indexed and the idex value is
within the bounds of the length of the string.

(rdar://139106996)

Co-authored-by: MalavikaSamak <malavika2 at apple.com>

Added: 
    

Modified: 
    clang/lib/Analysis/UnsafeBufferUsage.cpp
    clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp

Removed: 
    


################################################################################
diff  --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 2c68409b846bc8..b683826503c74c 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -436,21 +436,31 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
 
   const auto *BaseDRE =
       dyn_cast<DeclRefExpr>(Node.getBase()->IgnoreParenImpCasts());
-  if (!BaseDRE)
-    return false;
-  if (!BaseDRE->getDecl())
-    return false;
-  const auto *CATy = Finder->getASTContext().getAsConstantArrayType(
-      BaseDRE->getDecl()->getType());
-  if (!CATy)
+  const auto *SLiteral =
+      dyn_cast<StringLiteral>(Node.getBase()->IgnoreParenImpCasts());
+  uint64_t size;
+
+  if (!BaseDRE && !SLiteral)
     return false;
 
+  if (BaseDRE) {
+    if (!BaseDRE->getDecl())
+      return false;
+    const auto *CATy = Finder->getASTContext().getAsConstantArrayType(
+        BaseDRE->getDecl()->getType());
+    if (!CATy) {
+      return false;
+    }
+    size = CATy->getLimitedSize();
+  } else if (SLiteral) {
+    size = SLiteral->getLength() + 1;
+  }
+
   if (const auto *IdxLit = dyn_cast<IntegerLiteral>(Node.getIdx())) {
     const APInt ArrIdx = IdxLit->getValue();
     // FIXME: ArrIdx.isNegative() we could immediately emit an error as that's a
     // bug
-    if (ArrIdx.isNonNegative() &&
-        ArrIdx.getLimitedValue() < CATy->getLimitedSize())
+    if (ArrIdx.isNonNegative() && ArrIdx.getLimitedValue() < size)
       return true;
   }
 

diff  --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
index 8b2f103ec66708..c6c93a27e4b969 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
@@ -38,3 +38,17 @@ void constant_idx_unsafe(unsigned idx) {
                         // expected-note at -1{{change type of 'buffer' to 'std::array' to label it for hardening}}
   buffer[10] = 0;       // expected-note{{used in buffer access here}}
 }
+
+void constant_id_string(unsigned idx) {
+  char safe_char = "abc"[1]; // no-warning
+  safe_char = ""[0];
+  safe_char = "\0"[0];
+ 
+  char abcd[5] = "abc";
+  abcd[2]; // no-warning
+
+  char unsafe_char = "abc"[3];
+  unsafe_char = "abc"[-1]; //expected-warning{{unsafe buffer access}}
+  unsafe_char = ""[1]; //expected-warning{{unsafe buffer access}} 
+  unsafe_char = ""[idx]; //expected-warning{{unsafe buffer access}}
+}


        


More information about the cfe-commits mailing list