Skip to content

[-Wunsafe-buffer-usage] Fix false positives for string literals #115554

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

jkorous-apple
Copy link
Contributor

fixes rdar://139106996

# Conflicts:
#	clang/lib/Analysis/UnsafeBufferUsage.cpp
@llvmbot llvmbot added clang Clang issues not falling into any other category clang:analysis labels Nov 8, 2024
@llvmbot
Copy link
Member

llvmbot commented Nov 8, 2024

@llvm/pr-subscribers-clang

@llvm/pr-subscribers-clang-analysis

Author: None (jkorous-apple)

Changes

fixes rdar://139106996


Full diff: https://github.com/llvm/llvm-project/pull/115554.diff

2 Files Affected:

  • (modified) clang/lib/Analysis/UnsafeBufferUsage.cpp (+16-10)
  • (added) clang/test/SemaCXX/warn-unsafe-buffer-usage-string-literal.cpp (+18)
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 2c68409b846bc8..116d098075b6bf 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -434,16 +434,22 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
   //    already duplicated
   //  - call both from Sema and from here
 
-  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)
-    return false;
+  APInt ArrSize{};
+  if (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)
+      return false;
+    ArrSize = CATy->getSize();
+  } else if (const auto *BaseStrLit = dyn_cast<StringLiteral>(Node.getBase()->IgnoreParenImpCasts())) {
+    // Add 1 for the terminating null character.
+    ArrSize = APInt{64, BaseStrLit->getLength() + 1, false};
+  }
 
   if (const auto *IdxLit = dyn_cast<IntegerLiteral>(Node.getIdx())) {
     const APInt ArrIdx = IdxLit->getValue();
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-string-literal.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-string-literal.cpp
new file mode 100644
index 00000000000000..e983a8f135d8a4
--- /dev/null
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-string-literal.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -std=c++20 -Wno-everything -Wunsafe-buffer-usage \
+// RUN:            -fsafe-buffer-usage-suggestions \
+// RUN:            -verify %s
+
+// CHECK-NOT: [-Wunsafe-buffer-usage]
+
+
+void foo(unsigned idx) {
+  char c = '0';
+  c = "abc"[0];
+  c = "abc"[1];
+  c = "abc"[2];
+  c = "abc"[3];
+  c = "abc"[4]; // expected-warning{{unsafe buffer access}}
+  c = "abc"[idx]; // expected-warning{{unsafe buffer access}}
+  c = ""[0];
+  c = ""[1]; // expected-warning{{unsafe buffer access}}
+}

Copy link

github-actions bot commented Nov 8, 2024

⚠️ C/C++ code formatter, clang-format found issues in your code. ⚠️

You can test this locally with the following command:
git-clang-format --diff 8a7a7b5ffc690bd012cf090d31d47ec938248ba3 8db304f11ba708abd096b4b8df998c55548e5b4d --extensions cpp -- clang/test/SemaCXX/warn-unsafe-buffer-usage-string-literal.cpp clang/lib/Analysis/UnsafeBufferUsage.cpp
View the diff from clang-format here.
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 116d098075..65a4fecd54 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -436,7 +436,7 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
 
   APInt ArrSize{};
   if (const auto *BaseDRE =
-    dyn_cast<DeclRefExpr>(Node.getBase()->IgnoreParenImpCasts())) {
+          dyn_cast<DeclRefExpr>(Node.getBase()->IgnoreParenImpCasts())) {
     if (!BaseDRE)
       return false;
     if (!BaseDRE->getDecl())
@@ -446,7 +446,8 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
     if (!CATy)
       return false;
     ArrSize = CATy->getSize();
-  } else if (const auto *BaseStrLit = dyn_cast<StringLiteral>(Node.getBase()->IgnoreParenImpCasts())) {
+  } else if (const auto *BaseStrLit = dyn_cast<StringLiteral>(
+                 Node.getBase()->IgnoreParenImpCasts())) {
     // Add 1 for the terminating null character.
     ArrSize = APInt{64, BaseStrLit->getLength() + 1, false};
   }

@jkorous-apple jkorous-apple marked this pull request as draft November 8, 2024 22:27
@malavikasamak
Copy link
Contributor

I think we can close this PR, since we already merged this as part of #115552

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
clang:analysis clang Clang issues not falling into any other category
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants