[clang] [Wunsafe-buffer-usage] Turn off unsafe-buffer warning for methods annotated with clang::unsafe_buffer_usage attribute (PR #125671)

Malavika Samak via cfe-commits cfe-commits at lists.llvm.org
Mon Feb 24 10:05:37 PST 2025


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

>From 821a4b46705375bb34e207d406d8d7e9a2818f85 Mon Sep 17 00:00:00 2001
From: MalavikaSamak <malavika2 at apple.com>
Date: Fri, 31 Jan 2025 13:19:46 +0530
Subject: [PATCH 1/3] [Wunsafe-buffer-usage] Turn off unsafe-buffer warning for
 methods annotated with clang::unsafe_buffer_usage attribute

Unsafe operation in methods that are already annotated with clang::unsafe_buffer_usage attribute,
should not trigger a warning. This is because, the developer has already identified
the method as unsafe and warning at every unsafe operation is redundant.

(rdar://138644831)
---
 clang/docs/ReleaseNotes.rst                   |  2 +
 clang/lib/Sema/AnalysisBasedWarnings.cpp      |  3 ++
 ...warn-unsafe-buffer-usage-function-attr.cpp | 47 ++++++++++++++++---
 3 files changed, 46 insertions(+), 6 deletions(-)

diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 30364a747f9c1..b4d2ba043bfb5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -109,6 +109,8 @@ Removed Compiler Flags
 
 Attribute Changes in Clang
 --------------------------
+Adding [[clang::unsafe_buffer_usage]] attribute to a method definition now turns off all -Wunsafe-buffer-usage
+related warnings within the method body.
 
 Improvements to Clang's diagnostics
 -----------------------------------
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 589869d018657..ef87efc9b9942 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -2610,6 +2610,9 @@ void clang::sema::AnalysisBasedWarnings::IssueWarnings(
 
   // The Callback function that performs analyses:
   auto CallAnalyzers = [&](const Decl *Node) -> void {
+    if (Node->hasAttr<UnsafeBufferUsageAttr>())
+      return;
+
     // Perform unsafe buffer usage analysis:
     if (!Diags.isIgnored(diag::warn_unsafe_buffer_operation,
                          Node->getBeginLoc()) ||
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-function-attr.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-function-attr.cpp
index 724d444638b57..ef724acc761db 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-function-attr.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-function-attr.cpp
@@ -119,16 +119,15 @@ struct HoldsUnsafeMembers {
 
     [[clang::unsafe_buffer_usage]]
     HoldsUnsafeMembers(int i)
-        : FromCtor(i),  // expected-warning{{function introduces unsafe buffer manipulation}}
-          FromCtor2{i}  // expected-warning{{function introduces unsafe buffer manipulation}}
-    {}
+        : FromCtor(i),
+          FromCtor2{i} {}
 
     HoldsUnsafeMembers(float f)
         : HoldsUnsafeMembers(0) {}  // expected-warning{{function introduces unsafe buffer manipulation}}
 
     UnsafeMembers FromCtor;
     UnsafeMembers FromCtor2;
-    UnsafeMembers FromField{3};  // expected-warning 2{{function introduces unsafe buffer manipulation}}
+    UnsafeMembers FromField{3};  // expected-warning {{function introduces unsafe buffer manipulation}}
 };
 
 struct SubclassUnsafeMembers : public UnsafeMembers {
@@ -138,8 +137,7 @@ struct SubclassUnsafeMembers : public UnsafeMembers {
 
     [[clang::unsafe_buffer_usage]]
     SubclassUnsafeMembers(int i)
-        : UnsafeMembers(i)  // expected-warning{{function introduces unsafe buffer manipulation}}
-    {}
+        : UnsafeMembers(i){}
 };
 
 // https://github.com/llvm/llvm-project/issues/80482
@@ -245,3 +243,40 @@ struct AggregateViaDefaultInit {
 void testAggregateViaDefaultInit() {
     AggregateViaDefaultInit A;
 };
+
+struct A {
+  int arr[2];
+
+  [[clang::unsafe_buffer_usage]]
+  int *ptr;
+};
+
+namespace std{
+  template <typename T> class span {
+
+   T *elements;
+
+   public:
+
+   constexpr span(T *, unsigned){}
+
+   template<class Begin, class End>
+   constexpr span(Begin first, End last){}
+
+   constexpr T* data() const noexcept {
+     return elements;
+   }
+ };
+}
+
+[[clang::unsafe_buffer_usage]]
+void check_no_warnings(unsigned idx) {
+  int *arr = new int[20];
+
+  int k = arr[idx]; // no-warning
+
+  std::span<int> sp = {arr, 20}; // no-warning
+  A *ptr = reinterpret_cast<A*> (sp.data()); // no-warning
+  A a;
+  a.ptr = arr; // no-warning
+}

>From b37f48fb71100821a7be3e00c57418603f26935e Mon Sep 17 00:00:00 2001
From: MalavikaSamak <malavika2 at apple.com>
Date: Fri, 21 Feb 2025 11:09:10 -0800
Subject: [PATCH 2/3] Add additional tests to check suppression in variadic
 functions and their callers.

---
 .../warn-unsafe-buffer-usage-function-attr.cpp   | 16 ++++++++++++++++
 1 file changed, 16 insertions(+)

diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-function-attr.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-function-attr.cpp
index ef724acc761db..4318df930eb59 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-function-attr.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-function-attr.cpp
@@ -280,3 +280,19 @@ void check_no_warnings(unsigned idx) {
   A a;
   a.ptr = arr; // no-warning
 }
+
+[[clang::unsafe_buffer_usage]]
+void check_no_warning_variadic(unsigned idx, int arr[20], ...) {
+  int k = arr[idx]; // no-warning
+
+  std::span<int> sp = {arr, 20}; // no-warning
+  A *ptr = reinterpret_cast<A*> (sp.data()); // no-warning
+  A a;
+  a.ptr = arr; // no-warning
+}
+
+void invoke_methods() {
+  int array[20];
+  check_no_warnings(30); //expected-warning{{function introduces unsafe buffer manipulation}}
+  check_no_warning_variadic(20, array); //expected-warning{{function introduces unsafe buffer manipulation}}
+}

>From e918986a7760342d41df3f1e6eb12c9e7f8431ab Mon Sep 17 00:00:00 2001
From: MalavikaSamak <malavika2 at apple.com>
Date: Mon, 24 Feb 2025 10:04:24 -0800
Subject: [PATCH 3/3] Adding a test to check behavior with templated methods.

---
 .../warn-unsafe-buffer-usage-function-attr.cpp     | 14 +++++++++++++-
 1 file changed, 13 insertions(+), 1 deletion(-)

diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-function-attr.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-function-attr.cpp
index 4318df930eb59..f3abe87928400 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-function-attr.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-function-attr.cpp
@@ -291,8 +291,20 @@ void check_no_warning_variadic(unsigned idx, int arr[20], ...) {
   a.ptr = arr; // no-warning
 }
 
+template<typename T>
+[[clang::unsafe_buffer_usage]]
+void check_no_warnings_template(unsigned idx, T* arr) {
+  int k = arr[idx]; // no-warning
+
+  std::span<int> sp = {arr, 20}; // no-warning
+  A *ptr = reinterpret_cast<A*> (sp.data()); // no-warning
+  A a;
+  a.ptr = arr; // no-warning
+}
+
 void invoke_methods() {
   int array[20];
   check_no_warnings(30); //expected-warning{{function introduces unsafe buffer manipulation}}
-  check_no_warning_variadic(20, array); //expected-warning{{function introduces unsafe buffer manipulation}}
+  check_no_warning_variadic(15, array); //expected-warning{{function introduces unsafe buffer manipulation}}
+  check_no_warnings_template(10, array); //expected-warning{{function introduces unsafe buffer manipulation}}
 }



More information about the cfe-commits mailing list