Skip to content

[-Wunsafe-buffer-usage] Suppress warning for multi-dimensional constant arrays #118249

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

Merged
merged 1 commit into from
Dec 12, 2024

Conversation

malavikasamak
Copy link
Contributor

@malavikasamak malavikasamak commented Dec 2, 2024

Do not warn about unsafe buffer access, when multi-dimensional constant arrays are accessed and their indices are within the bounds of the buffer. Warning in such cases would be a false positive. Such a suppression already exists for 1-d
arrays and it is now extended to multi-dimensional arrays.

(rdar://137926311)
(rdar://140320139)

Copy link

graphite-app bot commented Dec 2, 2024

Your org has enabled the Graphite merge queue for merging into main

Add the label “FP Bundles” to the PR and Graphite will automatically add it to the merge queue when it’s ready to merge.

You must have a Graphite account and log in to Graphite in order to use the merge queue. Sign up using this link.

@llvmbot llvmbot added clang Clang issues not falling into any other category clang:analysis labels Dec 2, 2024
@llvmbot
Copy link
Member

llvmbot commented Dec 2, 2024

@llvm/pr-subscribers-clang

Author: Malavika Samak (malavikasamak)

Changes

Do not warn about unsafe buffer access, when 2-D constant arrays are accessed and the indices are within the bounds of the buffer. Warning in such cases is a false postive. Such a suppression aleady exists for 1-d arrays and it is now extended to 2-D arrays.

(rdar://137926311)


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

5 Files Affected:

  • (modified) clang/lib/Analysis/UnsafeBufferUsage.cpp (+49-15)
  • (modified) clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp (+6)
  • (modified) clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-main.cpp (+1-2)
  • (modified) clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-unsupported.cpp (+1-1)
  • (modified) clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp (+11-22)
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 5f36ffa926b269..f1e3b28fc03249 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -433,20 +433,56 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
   //    already duplicated
   //  - call both from Sema and from here
 
-  const auto *BaseDRE =
+  auto CheckBounds = [](const ArraySubscriptExpr *ASE, uint64_t limit) -> bool {
+    if (const auto *IdxLit = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
+      const APInt ArrIdx = IdxLit->getValue();
+      if (ArrIdx.isNonNegative() && ArrIdx.getLimitedValue() < limit)
+        return true;
+    }
+    return false;
+  };
+
+  const auto *BaseASE =
+      dyn_cast<ArraySubscriptExpr>(Node.getBase()->IgnoreParenImpCasts());
+  uint64_t size = 0;
+
+  if (BaseASE) {
+    const auto *DRE =
+        dyn_cast<DeclRefExpr>(BaseASE->getBase()->IgnoreParenImpCasts());
+
+    if (!DRE)
+      return false;
+
+    const auto *CATy = dyn_cast<ConstantArrayType>(
+        DRE->getType()->getUnqualifiedDesugaredType());
+    if (!CATy) {
+      return false;
+    }
+    size = CATy->getLimitedSize();
+
+    if (!CheckBounds(BaseASE, size))
+      return false;
+
+    CATy = Finder->getASTContext().getAsConstantArrayType(BaseASE->getType());
+    if (!CATy) {
+      return false;
+    }
+
+    size = CATy->getLimitedSize();
+    return CheckBounds(&Node, size);
+  }
+
+  const DeclRefExpr *BaseDRE =
       dyn_cast<DeclRefExpr>(Node.getBase()->IgnoreParenImpCasts());
   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());
+    const auto *CATy =
+        Finder->getASTContext().getAsConstantArrayType(BaseDRE->getType());
     if (!CATy) {
       return false;
     }
@@ -455,15 +491,7 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
     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() < size)
-      return true;
-  }
-
-  return false;
+  return CheckBounds(&Node, size);
 }
 
 AST_MATCHER_P(CallExpr, hasNumArgs, unsigned, Num) {
@@ -1172,6 +1200,12 @@ class ArraySubscriptGadget : public WarningGadget {
     if (const auto *DRE =
             dyn_cast<DeclRefExpr>(ASE->getBase()->IgnoreParenImpCasts())) {
       return {DRE};
+    } else if (const auto *BaseASE = dyn_cast<ArraySubscriptExpr>(
+                   ASE->getBase()->IgnoreParenImpCasts())) {
+      if (const auto *DRE = dyn_cast<DeclRefExpr>(
+              BaseASE->getBase()->IgnoreParenImpCasts())) {
+        return {DRE};
+      }
     }
 
     return {};
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
index c6c93a27e4b969..41cdc122b7d2fa 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
@@ -52,3 +52,9 @@ void constant_id_string(unsigned idx) {
   unsafe_char = ""[1]; //expected-warning{{unsafe buffer access}} 
   unsafe_char = ""[idx]; //expected-warning{{unsafe buffer access}}
 }
+
+typedef float Float4x4[4][4];
+
+float multi_dimension_array(Float4x4& matrix) {
+  return matrix[1][1];
+}
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-main.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-main.cpp
index c6b095031e0e32..d1fd1c00a9ea34 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-main.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-main.cpp
@@ -8,6 +8,5 @@
 // main function
 int main(int argc, char *argv[]) { // expected-warning{{'argv' is an unsafe pointer used for buffer access}}
   char tmp;
-  tmp = argv[5][5];                // expected-note{{used in buffer access here}} \
-				      expected-warning{{unsafe buffer access}}
+  tmp = argv[5][5];                // expected-note2{{used in buffer access here}}
 }
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-unsupported.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-unsupported.cpp
index 71350098613d19..5b22a5c5f8acfb 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-unsupported.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-unsupported.cpp
@@ -118,7 +118,7 @@ void isArrayDecayToPointerUPC(int a[][10], int (*b)[10]) {
 // expected-warning@-2{{'b' is an unsafe pointer used for buffer access}}
   int tmp;
 
-  tmp = a[5][5] + b[5][5];  // expected-warning2{{unsafe buffer access}}  expected-note2{{used in buffer access here}}
+  tmp = a[5][5] + b[5][5];  // expected-note4{{used in buffer access here}}
 }
 
 // parameter having default values:
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
index 642db0e9d3c632..5d75aa66a0781f 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
@@ -40,12 +40,9 @@ void testArraySubscripts(int idx, int *p, int **pp) {
 // expected-warning@-1{{'p' is an unsafe pointer used for buffer access}}
 // expected-warning@-2{{'pp' is an unsafe pointer used for buffer access}}
   foo(p[1],             // expected-note{{used in buffer access here}}
-      pp[1][1],         // expected-note{{used in buffer access here}}
-                        // expected-warning@-1{{unsafe buffer access}}
-      1[1[pp]],         // expected-note{{used in buffer access here}}
-                        // expected-warning@-1{{unsafe buffer access}}
-      1[pp][1]          // expected-note{{used in buffer access here}}
-                        // expected-warning@-1{{unsafe buffer access}}
+      pp[1][1],         // expected-note2{{used in buffer access here}}
+      1[1[pp]],         // expected-note2{{used in buffer access here}}
+      1[pp][1]          // expected-note2{{used in buffer access here}}
       );
 
   if (p[3]) {           // expected-note{{used in buffer access here}}
@@ -65,13 +62,9 @@ void testArraySubscripts(int idx, int *p, int **pp) {
     int b[10][10];      // expected-warning{{'b' is an unsafe buffer that does not perform bounds checks}}
 
   foo(a[idx], idx[a],   // expected-note2{{used in buffer access here}}
-      b[idx][idx + 1],  // expected-warning{{unsafe buffer access}}
-                        // expected-note@-1{{used in buffer access here}}
-      (idx + 1)[b][idx],// expected-warning{{unsafe buffer access}}
-                        // expected-note@-1{{used in buffer access here}}
-      (idx + 1)[idx[b]]);
-                        // expected-warning@-1{{unsafe buffer access}}
-                        // expected-note@-2{{used in buffer access here}}
+      b[idx][idx + 1],  // expected-note2{{used in buffer access here}}
+      (idx + 1)[b][idx],// expected-note2{{used in buffer access here}}
+      (idx + 1)[idx[b]]); // expected-note2{{used in buffer access here}}
 
   // Not to warn when index is zero
   foo(p[0], pp[0][0], 0[0[pp]], 0[pp][0],
@@ -108,8 +101,7 @@ void testQualifiedParameters(const int * p, const int * const q, const int a[10]
   foo(p[1], 1[p], p[-1],    // expected-note3{{used in buffer access here}}
       q[1], 1[q], q[-1],    // expected-note3{{used in buffer access here}}
       a[1],                 // expected-note{{used in buffer access here}}     `a` is of pointer type
-      b[1][2]               // expected-note{{used in buffer access here}}     `b[1]` is of array type
-                            // expected-warning@-1{{unsafe buffer access}}
+      b[1][2]               // expected-note2{{used in buffer access here}}     `b[1]` is of array type
       );
 }
 
@@ -223,10 +215,9 @@ template<typename T, int N> T f(T t, T * pt, T a[N], T (&b)[N]) {
   // expected-warning@-1{{'t' is an unsafe pointer used for buffer access}}
   // expected-warning@-2{{'pt' is an unsafe pointer used for buffer access}}
   // expected-warning@-3{{'a' is an unsafe pointer used for buffer access}}
-  // expected-warning@-4{{'b' is an unsafe buffer that does not perform bounds checks}}
   foo(pt[1],    // expected-note{{used in buffer access here}}
       a[1],     // expected-note{{used in buffer access here}}
-      b[1]);    // expected-note{{used in buffer access here}}
+      b[1]);    
   return &t[1]; // expected-note{{used in buffer access here}}
 }
 
@@ -366,17 +357,15 @@ int testArrayAccesses(int n, int idx) {
     // expected-warning@-1{{'cArr' is an unsafe buffer that does not perform bounds checks}}
     int d = cArr[0][0];
     foo(cArr[0][0]);
-    foo(cArr[idx][idx + 1]);        // expected-note{{used in buffer access here}}
-                                    // expected-warning@-1{{unsafe buffer access}}
-    auto cPtr = cArr[idx][idx * 2]; // expected-note{{used in buffer access here}}
-                                    // expected-warning@-1{{unsafe buffer access}}
+    foo(cArr[idx][idx + 1]);        // expected-note2{{used in buffer access here}}
+    auto cPtr = cArr[idx][idx * 2]; // expected-note2{{used in buffer access here}}
     foo(cPtr);
 
     // Typdefs
     typedef int A[3];
     const A tArr = {4, 5, 6};
     foo(tArr[0], tArr[1]);
-    return cArr[0][1];      // expected-warning{{unsafe buffer access}}
+    return cArr[0][1];      
 }
 
 void testArrayPtrArithmetic(int x[]) { // expected-warning{{'x' is an unsafe pointer used for buffer access}}

@llvmbot
Copy link
Member

llvmbot commented Dec 2, 2024

@llvm/pr-subscribers-clang-analysis

Author: Malavika Samak (malavikasamak)

Changes

Do not warn about unsafe buffer access, when 2-D constant arrays are accessed and the indices are within the bounds of the buffer. Warning in such cases is a false postive. Such a suppression aleady exists for 1-d arrays and it is now extended to 2-D arrays.

(rdar://137926311)


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

5 Files Affected:

  • (modified) clang/lib/Analysis/UnsafeBufferUsage.cpp (+49-15)
  • (modified) clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp (+6)
  • (modified) clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-main.cpp (+1-2)
  • (modified) clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-unsupported.cpp (+1-1)
  • (modified) clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp (+11-22)
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 5f36ffa926b269..f1e3b28fc03249 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -433,20 +433,56 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
   //    already duplicated
   //  - call both from Sema and from here
 
-  const auto *BaseDRE =
+  auto CheckBounds = [](const ArraySubscriptExpr *ASE, uint64_t limit) -> bool {
+    if (const auto *IdxLit = dyn_cast<IntegerLiteral>(ASE->getIdx())) {
+      const APInt ArrIdx = IdxLit->getValue();
+      if (ArrIdx.isNonNegative() && ArrIdx.getLimitedValue() < limit)
+        return true;
+    }
+    return false;
+  };
+
+  const auto *BaseASE =
+      dyn_cast<ArraySubscriptExpr>(Node.getBase()->IgnoreParenImpCasts());
+  uint64_t size = 0;
+
+  if (BaseASE) {
+    const auto *DRE =
+        dyn_cast<DeclRefExpr>(BaseASE->getBase()->IgnoreParenImpCasts());
+
+    if (!DRE)
+      return false;
+
+    const auto *CATy = dyn_cast<ConstantArrayType>(
+        DRE->getType()->getUnqualifiedDesugaredType());
+    if (!CATy) {
+      return false;
+    }
+    size = CATy->getLimitedSize();
+
+    if (!CheckBounds(BaseASE, size))
+      return false;
+
+    CATy = Finder->getASTContext().getAsConstantArrayType(BaseASE->getType());
+    if (!CATy) {
+      return false;
+    }
+
+    size = CATy->getLimitedSize();
+    return CheckBounds(&Node, size);
+  }
+
+  const DeclRefExpr *BaseDRE =
       dyn_cast<DeclRefExpr>(Node.getBase()->IgnoreParenImpCasts());
   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());
+    const auto *CATy =
+        Finder->getASTContext().getAsConstantArrayType(BaseDRE->getType());
     if (!CATy) {
       return false;
     }
@@ -455,15 +491,7 @@ AST_MATCHER(ArraySubscriptExpr, isSafeArraySubscript) {
     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() < size)
-      return true;
-  }
-
-  return false;
+  return CheckBounds(&Node, size);
 }
 
 AST_MATCHER_P(CallExpr, hasNumArgs, unsigned, Num) {
@@ -1172,6 +1200,12 @@ class ArraySubscriptGadget : public WarningGadget {
     if (const auto *DRE =
             dyn_cast<DeclRefExpr>(ASE->getBase()->IgnoreParenImpCasts())) {
       return {DRE};
+    } else if (const auto *BaseASE = dyn_cast<ArraySubscriptExpr>(
+                   ASE->getBase()->IgnoreParenImpCasts())) {
+      if (const auto *DRE = dyn_cast<DeclRefExpr>(
+              BaseASE->getBase()->IgnoreParenImpCasts())) {
+        return {DRE};
+      }
     }
 
     return {};
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
index c6c93a27e4b969..41cdc122b7d2fa 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-array.cpp
@@ -52,3 +52,9 @@ void constant_id_string(unsigned idx) {
   unsafe_char = ""[1]; //expected-warning{{unsafe buffer access}} 
   unsafe_char = ""[idx]; //expected-warning{{unsafe buffer access}}
 }
+
+typedef float Float4x4[4][4];
+
+float multi_dimension_array(Float4x4& matrix) {
+  return matrix[1][1];
+}
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-main.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-main.cpp
index c6b095031e0e32..d1fd1c00a9ea34 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-main.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-main.cpp
@@ -8,6 +8,5 @@
 // main function
 int main(int argc, char *argv[]) { // expected-warning{{'argv' is an unsafe pointer used for buffer access}}
   char tmp;
-  tmp = argv[5][5];                // expected-note{{used in buffer access here}} \
-				      expected-warning{{unsafe buffer access}}
+  tmp = argv[5][5];                // expected-note2{{used in buffer access here}}
 }
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-unsupported.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-unsupported.cpp
index 71350098613d19..5b22a5c5f8acfb 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-unsupported.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-fixits-parm-unsupported.cpp
@@ -118,7 +118,7 @@ void isArrayDecayToPointerUPC(int a[][10], int (*b)[10]) {
 // expected-warning@-2{{'b' is an unsafe pointer used for buffer access}}
   int tmp;
 
-  tmp = a[5][5] + b[5][5];  // expected-warning2{{unsafe buffer access}}  expected-note2{{used in buffer access here}}
+  tmp = a[5][5] + b[5][5];  // expected-note4{{used in buffer access here}}
 }
 
 // parameter having default values:
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
index 642db0e9d3c632..5d75aa66a0781f 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage.cpp
@@ -40,12 +40,9 @@ void testArraySubscripts(int idx, int *p, int **pp) {
 // expected-warning@-1{{'p' is an unsafe pointer used for buffer access}}
 // expected-warning@-2{{'pp' is an unsafe pointer used for buffer access}}
   foo(p[1],             // expected-note{{used in buffer access here}}
-      pp[1][1],         // expected-note{{used in buffer access here}}
-                        // expected-warning@-1{{unsafe buffer access}}
-      1[1[pp]],         // expected-note{{used in buffer access here}}
-                        // expected-warning@-1{{unsafe buffer access}}
-      1[pp][1]          // expected-note{{used in buffer access here}}
-                        // expected-warning@-1{{unsafe buffer access}}
+      pp[1][1],         // expected-note2{{used in buffer access here}}
+      1[1[pp]],         // expected-note2{{used in buffer access here}}
+      1[pp][1]          // expected-note2{{used in buffer access here}}
       );
 
   if (p[3]) {           // expected-note{{used in buffer access here}}
@@ -65,13 +62,9 @@ void testArraySubscripts(int idx, int *p, int **pp) {
     int b[10][10];      // expected-warning{{'b' is an unsafe buffer that does not perform bounds checks}}
 
   foo(a[idx], idx[a],   // expected-note2{{used in buffer access here}}
-      b[idx][idx + 1],  // expected-warning{{unsafe buffer access}}
-                        // expected-note@-1{{used in buffer access here}}
-      (idx + 1)[b][idx],// expected-warning{{unsafe buffer access}}
-                        // expected-note@-1{{used in buffer access here}}
-      (idx + 1)[idx[b]]);
-                        // expected-warning@-1{{unsafe buffer access}}
-                        // expected-note@-2{{used in buffer access here}}
+      b[idx][idx + 1],  // expected-note2{{used in buffer access here}}
+      (idx + 1)[b][idx],// expected-note2{{used in buffer access here}}
+      (idx + 1)[idx[b]]); // expected-note2{{used in buffer access here}}
 
   // Not to warn when index is zero
   foo(p[0], pp[0][0], 0[0[pp]], 0[pp][0],
@@ -108,8 +101,7 @@ void testQualifiedParameters(const int * p, const int * const q, const int a[10]
   foo(p[1], 1[p], p[-1],    // expected-note3{{used in buffer access here}}
       q[1], 1[q], q[-1],    // expected-note3{{used in buffer access here}}
       a[1],                 // expected-note{{used in buffer access here}}     `a` is of pointer type
-      b[1][2]               // expected-note{{used in buffer access here}}     `b[1]` is of array type
-                            // expected-warning@-1{{unsafe buffer access}}
+      b[1][2]               // expected-note2{{used in buffer access here}}     `b[1]` is of array type
       );
 }
 
@@ -223,10 +215,9 @@ template<typename T, int N> T f(T t, T * pt, T a[N], T (&b)[N]) {
   // expected-warning@-1{{'t' is an unsafe pointer used for buffer access}}
   // expected-warning@-2{{'pt' is an unsafe pointer used for buffer access}}
   // expected-warning@-3{{'a' is an unsafe pointer used for buffer access}}
-  // expected-warning@-4{{'b' is an unsafe buffer that does not perform bounds checks}}
   foo(pt[1],    // expected-note{{used in buffer access here}}
       a[1],     // expected-note{{used in buffer access here}}
-      b[1]);    // expected-note{{used in buffer access here}}
+      b[1]);    
   return &t[1]; // expected-note{{used in buffer access here}}
 }
 
@@ -366,17 +357,15 @@ int testArrayAccesses(int n, int idx) {
     // expected-warning@-1{{'cArr' is an unsafe buffer that does not perform bounds checks}}
     int d = cArr[0][0];
     foo(cArr[0][0]);
-    foo(cArr[idx][idx + 1]);        // expected-note{{used in buffer access here}}
-                                    // expected-warning@-1{{unsafe buffer access}}
-    auto cPtr = cArr[idx][idx * 2]; // expected-note{{used in buffer access here}}
-                                    // expected-warning@-1{{unsafe buffer access}}
+    foo(cArr[idx][idx + 1]);        // expected-note2{{used in buffer access here}}
+    auto cPtr = cArr[idx][idx * 2]; // expected-note2{{used in buffer access here}}
     foo(cPtr);
 
     // Typdefs
     typedef int A[3];
     const A tArr = {4, 5, 6};
     foo(tArr[0], tArr[1]);
-    return cArr[0][1];      // expected-warning{{unsafe buffer access}}
+    return cArr[0][1];      
 }
 
 void testArrayPtrArithmetic(int x[]) { // expected-warning{{'x' is an unsafe pointer used for buffer access}}

@malavikasamak malavikasamak force-pushed the msamak-fp-multid-array branch from 1b21a2e to 8ca3b63 Compare December 2, 2024 09:05
@malavikasamak malavikasamak changed the title [-Wunsafe-buffer-usage] Suppress warning when 2-D constant arrays are indexed [-Wunsafe-buffer-usage] Suppress warning for multi-dimensional constant arrays Dec 2, 2024
@malavikasamak malavikasamak force-pushed the msamak-fp-multid-array branch 2 times, most recently from a3bc09e to 2d923a6 Compare December 3, 2024 10:53
@jkorous-apple
Copy link
Contributor

jkorous-apple commented Dec 3, 2024

We want to suppress warnings for subscript operator on multi-dimensional constant size arrays (not array[]) only where the index used is constant and within bounds.
You changed some test cases where multi-dimensional pointers are accessed. For those the upper bound is unknown at compile time and we need to keep the warning.

@malavikasamak malavikasamak force-pushed the msamak-fp-multid-array branch 3 times, most recently from 3a73ee4 to e1eadf4 Compare December 7, 2024 05:35
Copy link

github-actions bot commented Dec 7, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

…nt arrays

Do not warn about unsafe buffer access, when multi-dimensional constant arrays
are accessed and their indices are within the bounds of the buffer. Warning in
such cases would be a false positive. Such a suppression already exists for 1-d
arrays and it is now extended to multi-dimensional arrays.

(rdar://137926311)
(rdar://140320139)
@malavikasamak malavikasamak force-pushed the msamak-fp-multid-array branch from e1eadf4 to c1f7c2b Compare December 7, 2024 05:55
Copy link
Contributor

@ziqingluo-90 ziqingluo-90 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks.

@malavikasamak
Copy link
Contributor Author

LGTM! Thanks.

Thanks @ziqingluo-90

@malavikasamak
Copy link
Contributor Author

@jkorous-apple: If there are no objections, I will go ahead and merge this PR.

Copy link
Contributor

@jkorous-apple jkorous-apple left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@malavikasamak malavikasamak merged commit 9c50182 into llvm:main Dec 12, 2024
8 checks passed
@llvm-ci
Copy link
Collaborator

llvm-ci commented Dec 12, 2024

LLVM Buildbot has detected a new failure on builder openmp-offload-amdgpu-runtime running on omp-vega20-0 while building clang at step 7 "Add check check-offload".

Full details are available at: https://lab.llvm.org/buildbot/#/builders/30/builds/12117

Here is the relevant piece of the build log for the reference
Step 7 (Add check check-offload) failure: test (failure)
******************** TEST 'libomptarget :: amdgcn-amd-amdhsa :: sanitizer/kernel_crash_async.c' FAILED ********************
Exit Code: 1

Command Output (stdout):
--
# RUN: at line 2
/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/clang -fopenmp    -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src  -nogpulib -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib  -fopenmp-targets=amdgcn-amd-amdhsa -O3 /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/sanitizer/kernel_crash_async.c -o /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/sanitizer/Output/kernel_crash_async.c.tmp /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib/libomptarget.devicertl.a
# executed command: /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/clang -fopenmp -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -nogpulib -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib -fopenmp-targets=amdgcn-amd-amdhsa -O3 /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/sanitizer/kernel_crash_async.c -o /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/sanitizer/Output/kernel_crash_async.c.tmp /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib/libomptarget.devicertl.a
# note: command had no output on stdout or stderr
# RUN: at line 3
/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/not --crash env -u LLVM_DISABLE_SYMBOLIZATION OFFLOAD_TRACK_NUM_KERNEL_LAUNCH_TRACES=1 /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/sanitizer/Output/kernel_crash_async.c.tmp 2>&1 | /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/FileCheck /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/sanitizer/kernel_crash_async.c --check-prefixes=TRACE
# executed command: /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/not --crash env -u LLVM_DISABLE_SYMBOLIZATION OFFLOAD_TRACK_NUM_KERNEL_LAUNCH_TRACES=1 /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/sanitizer/Output/kernel_crash_async.c.tmp
# note: command had no output on stdout or stderr
# executed command: /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/FileCheck /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/sanitizer/kernel_crash_async.c --check-prefixes=TRACE
# note: command had no output on stdout or stderr
# RUN: at line 4
/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/not --crash /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/sanitizer/Output/kernel_crash_async.c.tmp 2>&1 | /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/FileCheck /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/sanitizer/kernel_crash_async.c --check-prefixes=CHECK
# executed command: /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/not --crash /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/sanitizer/Output/kernel_crash_async.c.tmp
# note: command had no output on stdout or stderr
# executed command: /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/FileCheck /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/sanitizer/kernel_crash_async.c --check-prefixes=CHECK
# note: command had no output on stdout or stderr
# RUN: at line 5
/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/clang -fopenmp    -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src  -nogpulib -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib  -fopenmp-targets=amdgcn-amd-amdhsa -O3 /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/sanitizer/kernel_crash_async.c -o /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/sanitizer/Output/kernel_crash_async.c.tmp /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib/libomptarget.devicertl.a -g
# executed command: /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/clang -fopenmp -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test -I /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib -L /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -nogpulib -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/openmp/runtime/src -Wl,-rpath,/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib -fopenmp-targets=amdgcn-amd-amdhsa -O3 /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/sanitizer/kernel_crash_async.c -o /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/sanitizer/Output/kernel_crash_async.c.tmp /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./lib/libomptarget.devicertl.a -g
# note: command had no output on stdout or stderr
# RUN: at line 6
/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/not --crash env -u LLVM_DISABLE_SYMBOLIZATION OFFLOAD_TRACK_NUM_KERNEL_LAUNCH_TRACES=1 /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/sanitizer/Output/kernel_crash_async.c.tmp 2>&1 | /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/FileCheck /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/sanitizer/kernel_crash_async.c --check-prefixes=TRACE
# executed command: /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/not --crash env -u LLVM_DISABLE_SYMBOLIZATION OFFLOAD_TRACK_NUM_KERNEL_LAUNCH_TRACES=1 /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/sanitizer/Output/kernel_crash_async.c.tmp
# note: command had no output on stdout or stderr
# executed command: /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/FileCheck /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/sanitizer/kernel_crash_async.c --check-prefixes=TRACE
# note: command had no output on stdout or stderr
# RUN: at line 7
/home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/not --crash /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/sanitizer/Output/kernel_crash_async.c.tmp 2>&1 | /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/FileCheck /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/sanitizer/kernel_crash_async.c --check-prefixes=CHECK
# executed command: /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/not --crash /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/runtimes/runtimes-bins/offload/test/amdgcn-amd-amdhsa/sanitizer/Output/kernel_crash_async.c.tmp
# note: command had no output on stdout or stderr
# executed command: /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.build/./bin/FileCheck /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/sanitizer/kernel_crash_async.c --check-prefixes=CHECK
# .---command stderr------------
# | /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/sanitizer/kernel_crash_async.c:39:11: error: CHECK: expected string not found in input
# | // CHECK: Kernel {{[0-9]}}: {{.*}} (__omp_offloading_{{.*}}_main_l29)
# |           ^
# | <stdin>:1:1: note: scanning from here
# | Display only launched kernel:
# | ^
# | <stdin>:2:23: note: possible intended match here
# | Kernel 'omp target in main @ 29 (__omp_offloading_802_b38838e_main_l29)'
# |                       ^
# | 
# | Input file: <stdin>
# | Check file: /home/ompworker/bbot/openmp-offload-amdgpu-runtime/llvm.src/offload/test/sanitizer/kernel_crash_async.c
# | 
...

malavikasamak added a commit to swiftlang/llvm-project that referenced this pull request Dec 13, 2024
…nt arrays (llvm#118249)

Do not warn about unsafe buffer access, when multi-dimensional constant
arrays are accessed and their indices are within the bounds of the
buffer. Warning in such cases would be a false positive. Such a
suppression already exists for 1-d
arrays and it is now extended to multi-dimensional arrays.

(rdar://137926311)
(rdar://140320139)

Co-authored-by: MalavikaSamak <[email protected]>
(cherry picked from commit 9c50182)
malavikasamak added a commit to swiftlang/llvm-project that referenced this pull request Dec 13, 2024
…array

[-Wunsafe-buffer-usage] Suppress warning for multi-dimensional constant arrays (llvm#118249)
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.

5 participants