[clang] [-Wunsafe-buffer-usage] Fix false positives in warning againt 2-parameter std::span constructor (PR #115797)

Malavika Samak via cfe-commits cfe-commits at lists.llvm.org
Mon Nov 11 22:25:16 PST 2024


https://github.com/malavikasamak updated https://github.com/llvm/llvm-project/pull/115797

>From a60c18973c0ea5b59c7c5f38813083e862f70e6e Mon Sep 17 00:00:00 2001
From: MalavikaSamak <malavika2 at apple.com>
Date: Mon, 11 Nov 2024 17:18:40 -0800
Subject: [PATCH 1/2] [-Wunsafe-buffer-usage] Fix false positive in warnging
 againt 2-parameter std::span constructor

Do not warn when two parameter constructor receives pointer address from a std::addressof method
and the span size is set to 1.

(rdar://139298119)
---
 clang/lib/Analysis/UnsafeBufferUsage.cpp        |  8 ++++++++
 ...buffer-usage-in-container-span-construct.cpp | 17 +++++++++++++++++
 2 files changed, 25 insertions(+)

diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 2c68409b846bc8..507e61564fc3f8 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -410,6 +410,14 @@ AST_MATCHER(CXXConstructExpr, isSafeSpanTwoParamConstruct) {
       // Check form 3:
       return Arg1CV && Arg1CV->isOne();
     break;
+  case Stmt::CallExprClass:
+    if(const auto *CE = dyn_cast<CallExpr>(Arg0)) {
+      const auto FnDecl = CE->getDirectCallee();
+      if(FnDecl && FnDecl->getNameAsString() == "addressof" && FnDecl->isInStdNamespace()) {
+        return Arg1CV && Arg1CV->isOne();
+      }
+    }
+    break;
   default:
     break;
   }
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-in-container-span-construct.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-in-container-span-construct.cpp
index c138fe088b3ba9..30b6d4ba9fb904 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-in-container-span-construct.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-in-container-span-construct.cpp
@@ -21,6 +21,12 @@ namespace std {
 
   template< class T >
   T&& move( T&& t ) noexcept;
+
+  template <class _Tp>
+  _Tp* addressof(_Tp& __x) {
+    return &__x;
+  }
+ 
 }
 
 namespace irrelevant_constructors {
@@ -74,15 +80,26 @@ namespace construct_wt_ptr_size {
     return std::span<int>{p, 10};                    // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
   }
 
+  // addressof method defined outside std namespace.
+  template <class _Tp>
+  _Tp* addressof(_Tp& __x) {
+    return &__x;
+  }
+
   void notWarnSafeCases(unsigned n, int *p) {
     int X;
     unsigned Y = 10;
     std::span<int> S = std::span{&X, 1}; // no-warning
+    S = std::span{std::addressof(X), 1}; // no-warning
     int Arr[10];
     typedef int TenInts_t[10];
     TenInts_t Arr2;
 
     S = std::span{&X, 2};                // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
+    S = std::span{std::addressof(X), 2}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
+    // Warn when a non std method also named addressof
+    S = std::span{addressof(X), 1}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}}
+
     S = std::span{new int[10], 10};      // no-warning
     S = std::span{new int[n], n};        // no-warning
     S = std::span{new int, 1};           // no-warning

>From 9b215f104ffa97c1be39f7666fe83dfedeaf8603 Mon Sep 17 00:00:00 2001
From: MalavikaSamak <malavika2 at apple.com>
Date: Mon, 11 Nov 2024 22:24:41 -0800
Subject: [PATCH 2/2] Fixing clang-format issues.

---
 clang/lib/Analysis/UnsafeBufferUsage.cpp | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 507e61564fc3f8..ae6863fb7cb28f 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -411,9 +411,10 @@ AST_MATCHER(CXXConstructExpr, isSafeSpanTwoParamConstruct) {
       return Arg1CV && Arg1CV->isOne();
     break;
   case Stmt::CallExprClass:
-    if(const auto *CE = dyn_cast<CallExpr>(Arg0)) {
+    if (const auto *CE = dyn_cast<CallExpr>(Arg0)) {
       const auto FnDecl = CE->getDirectCallee();
-      if(FnDecl && FnDecl->getNameAsString() == "addressof" && FnDecl->isInStdNamespace()) {
+      if (FnDecl && FnDecl->getNameAsString() == "addressof" &&
+          FnDecl->isInStdNamespace()) {
         return Arg1CV && Arg1CV->isOne();
       }
     }



More information about the cfe-commits mailing list