llvmbot wrote:

<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang

Author: Prajwal P J (pjalwadi)

<details>
<summary>Changes</summary>

"This patch extends the unsafe buffer usage warning to cover std::string_view 
constructors that take a pointer and size, similar to the existing check for 
std::span.

The warning message has been updated to be generic ('container construction' 
instead of 'span construction') and existing tests have been updated to match.

Fixes #<!-- -->166644."

---

Patch is 31.80 KiB, truncated to 20.00 KiB below, full version: 
https://github.com/llvm/llvm-project/pull/180471.diff


6 Files Affected:

- (modified) clang/docs/ReleaseNotes.rst (+3) 
- (modified) clang/include/clang/Basic/DiagnosticSemaKinds.td (+1-1) 
- (modified) clang/lib/Analysis/UnsafeBufferUsage.cpp (+2-1) 
- (modified) clang/test/SemaCXX/warn-unsafe-buffer-usage-field-attr.cpp (+1-1) 
- (modified) 
clang/test/SemaCXX/warn-unsafe-buffer-usage-in-container-span-construct.cpp 
(+62-62) 
- (added) clang/test/SemaCXX/warn-unsafe-buffer-usage-string-view.cpp (+20) 


``````````diff
diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst
index 7dc6881ed43e6..7dfba9afafeb5 100644
--- a/clang/docs/ReleaseNotes.rst
+++ b/clang/docs/ReleaseNotes.rst
@@ -204,6 +204,9 @@ Improvements to Clang's diagnostics
 
 - Improved ``-Wassign-enum`` performance by caching enum enumerator values. 
(#GH176454)
 
+- ``-Wunsafe-buffer-usage`` now warns about unsafe two-parameter constructors 
of 
+  ``std::string_view`` (pointer and size), consistent with the existing 
warning for ``std::span``.
+
 Improvements to Clang's time-trace
 ----------------------------------
 
diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td 
b/clang/include/clang/Basic/DiagnosticSemaKinds.td
index 71c478f4ca873..a792dff0d0b11 100644
--- a/clang/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td
@@ -13510,7 +13510,7 @@ def note_unsafe_buffer_variable_fixit_together : Note<
 def note_safe_buffer_usage_suggestions_disabled : Note<
   "pass -fsafe-buffer-usage-suggestions to receive code hardening 
suggestions">;
 def warn_unsafe_buffer_usage_in_container : Warning<
-  "the two-parameter std::span construction is unsafe as it can introduce 
mismatch between buffer size and the bound information">,
+  "the two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information">,
   InGroup<UnsafeBufferUsageInContainer>, DefaultIgnore;
 def warn_unsafe_buffer_usage_unique_ptr_array_access : Warning<"direct access 
using operator[] on std::unique_ptr<T[]> is unsafe due to lack of bounds 
checking">,
   InGroup<UnsafeBufferUsageInUniquePtrArrayAccess>, DefaultIgnore;
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp 
b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 761cdccc65d50..8d2049770b561 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -1785,7 +1785,8 @@ class SpanTwoParamConstructorGadget : public 
WarningGadget {
     const auto *CRecordDecl = CDecl->getParent();
     auto HasTwoParamSpanCtorDecl =
         CRecordDecl->isInStdNamespace() &&
-        CDecl->getDeclName().getAsString() == "span" && CE->getNumArgs() == 2;
+        (CDecl->getDeclName().getAsString() == "span" ||
+        CDecl->getDeclName().getAsString() == "basic_string_view") && 
CE->getNumArgs() == 2;
     if (!HasTwoParamSpanCtorDecl || isSafeSpanTwoParamConstruct(*CE, Ctx))
       return false;
     Result.addNode(SpanTwoParamConstructorTag, DynTypedNode::create(*CE));
diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-field-attr.cpp 
b/clang/test/SemaCXX/warn-unsafe-buffer-usage-field-attr.cpp
index 1636c948da075..024ba0ec81264 100644
--- a/clang/test/SemaCXX/warn-unsafe-buffer-usage-field-attr.cpp
+++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-field-attr.cpp
@@ -78,7 +78,7 @@ void test_writes_from_span(std::span<int> sp) {
 }
 
 void test_reads_to_span(A a, A b) {
-  //expected-warning@+1{{the two-parameter std::span construction is unsafe as 
it can introduce mismatch between buffer size and the bound information}}
+  //expected-warning@+1{{the two-parameter std::span or string_view 
construction is unsafe as it can introduce mismatch between buffer size and the 
bound information}}
   std::span<int> sp {a.ptr, a.sz}; //expected-warning{{field 'ptr' prone to 
unsafe buffer manipulation}}
 
   // expected-warning@+1 3{{field 'ptr' prone to unsafe buffer manipulation}}
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 1e7855517207e..107217a893c16 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
@@ -78,23 +78,23 @@ namespace irrelevant_constructors {
 
 namespace construct_wt_ptr_size {
   std::span<int> warnVarInit(int *p) {
-    std::span<int> S{p, 10};                     // expected-warning{{the 
two-parameter std::span construction is unsafe as it can introduce mismatch 
between buffer size and the bound information}}
-    std::span<int> S1(p, 10);                    // expected-warning{{the 
two-parameter std::span construction is unsafe as it can introduce mismatch 
between buffer size and the bound information}}
-    std::span<int> S2 = std::span{p, 10};        // expected-warning{{the 
two-parameter std::span construction is unsafe as it can introduce mismatch 
between buffer size and the bound information}}
-    std::span<int> S3 = std::span(p, 10);        // expected-warning{{the 
two-parameter std::span construction is unsafe as it can introduce mismatch 
between buffer size and the bound information}}
-    std::span<int> S4 = 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}}
-    std::span<int> S5 = 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}}
-    std::span<int> S6 = {p, 10};                 // expected-warning{{the 
two-parameter std::span construction is unsafe as it can introduce mismatch 
between buffer size and the bound information}}
-    auto S7 = 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}}
-    auto S8 = 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}}
-    const auto &S9 = 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}}
-    auto &&S10 = 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}}
+    std::span<int> S{p, 10};                     // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+    std::span<int> S1(p, 10);                    // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+    std::span<int> S2 = std::span{p, 10};        // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+    std::span<int> S3 = std::span(p, 10);        // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+    std::span<int> S4 = std::span<int>{p, 10};   // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+    std::span<int> S5 = std::span<int>(p, 10);   // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+    std::span<int> S6 = {p, 10};                 // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+    auto S7 = std::span<int>{p, 10};             // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+    auto S8 = std::span<int>(p, 10);             // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+    const auto &S9 = std::span<int>{p, 10};      // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+    auto &&S10 = std::span<int>(p, 10);          // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
 
 #define Ten 10
 
-    std::span S11 = std::span<int>{p, Ten};      // expected-warning{{the 
two-parameter std::span construction is unsafe as it can introduce mismatch 
between buffer size and the bound information}}
+    std::span S11 = std::span<int>{p, Ten};      // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
 
-    if (auto X = std::span<int>{p, Ten}; S10.data()) { // 
expected-warning{{the two-parameter std::span construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+    if (auto X = std::span<int>{p, Ten}; S10.data()) { // 
expected-warning{{the two-parameter std::span or string_view construction is 
unsafe as it can introduce mismatch between buffer size and the bound 
information}}
     }
 
     auto X = warnVarInit(p); // function return is fine
@@ -105,15 +105,15 @@ namespace construct_wt_ptr_size {
   void foo(const T &, const T &&, T);
 
   std::span<int> warnTemp(int *p) {
-    foo(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}}
-       std::move(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}}
-       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}}
+    foo(std::span<int>{p, 10},                       // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+       std::move(std::span<int>{p, 10}),            // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+       std::span<int>{p, 10});                      // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
 
-    std::span<int> Arr[1] = {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}}
+    std::span<int> Arr[1] = {std::span<int>{p, 10}}; // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
 
-    if (std::span<int>{p, 10}.data()) {              // expected-warning{{the 
two-parameter std::span construction is unsafe as it can introduce mismatch 
between buffer size and the bound information}}
+    if (std::span<int>{p, 10}.data()) {              // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
     }
-    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}}
+    return std::span<int>{p, 10};                    // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
   }
 
   // addressof method defined outside std namespace.
@@ -131,22 +131,22 @@ namespace construct_wt_ptr_size {
     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}}
+    S = std::span{&X, 2};                // expected-warning{{the 
two-parameter std::span or string_view 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 or string_view 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{addressof(X), 1}; // expected-warning{{the two-parameter 
std::span or string_view 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
-    S = std::span{new int, X};           // 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[n--], n--};    // 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], 11};      // 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], 9};       // expected-warning{{the 
two-parameter std::span construction is unsafe as it can introduce mismatch 
between buffer size and the bound information}}  // not smart enough to tell 
its safe
-    S = std::span{new int[10], Y};       // expected-warning{{the 
two-parameter std::span construction is unsafe as it can introduce mismatch 
between buffer size and the bound information}}  // not smart enough to tell 
its safe
+    S = std::span{new int, X};           // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+    S = std::span{new int[n--], n--};    // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+    S = std::span{new int[10], 11};      // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+    S = std::span{new int[10], 9};       // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}  // not 
smart enough to tell its safe
+    S = std::span{new int[10], Y};       // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}  // not 
smart enough to tell its safe
     S = std::span{Arr, 10};              // no-warning
     S = std::span{Arr2, 10};             // no-warning
-    S = std::span{Arr, Y};               // expected-warning{{the 
two-parameter std::span construction is unsafe as it can introduce mismatch 
between buffer size and the bound information}}  // not smart enough to tell 
its safe
+    S = std::span{Arr, Y};               // expected-warning{{the 
two-parameter std::span or string_view construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}  // not 
smart enough to tell its safe
     S = std::span{p, 0};                 // no-warning
   }
 } // namespace construct_wt_ptr_size
@@ -155,19 +155,19 @@ namespace construct_wt_begin_end {
   class It {};
 
   std::span<int> warnVarInit(It &First, It &Last) {
-    std::span<int> S{First, Last};                     // 
expected-warning{{the two-parameter std::span construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
-    std::span<int> S1(First, Last);                    // 
expected-warning{{the two-parameter std::span construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
-    std::span<int> S2 = std::span<int>{First, Last};   // 
expected-warning{{the two-parameter std::span construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
-    std::span<int> S3 = std::span<int>(First, Last);   // 
expected-warning{{the two-parameter std::span construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
-    std::span<int> S4 = std::span<int>{First, Last};   // 
expected-warning{{the two-parameter std::span construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
-    std::span<int> S5 = std::span<int>(First, Last);   // 
expected-warning{{the two-parameter std::span construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
-    std::span<int> S6 = {First, Last};                 // 
expected-warning{{the two-parameter std::span construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
-    auto S7 = std::span<int>{First, Last};             // 
expected-warning{{the two-parameter std::span construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
-    auto S8 = std::span<int>(First, Last);             // 
expected-warning{{the two-parameter std::span construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
-    const auto &S9 = std::span<int>{First, Last};      // 
expected-warning{{the two-parameter std::span construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
-    auto &&S10 = std::span<int>(First, Last);          // 
expected-warning{{the two-parameter std::span construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
-
-    if (auto X = std::span<int>{First, Last}; S10.data()) { // 
expected-warning{{the two-parameter std::span construction is unsafe as it can 
introduce mismatch between buffer size and the bound information}}
+    std::span<int> S{First, Last};                     // 
expected-warning{{the two-parameter std::span or string_view construction is 
unsafe as it can introduce mismatch between buffer size and the bound 
information}}
+    std::span<int> S1(First, Last);                    // 
expected-warning{{the two-parameter std::span or string_view construction is 
unsafe as it can introduce mismatch between buffer size and the bound 
information}}
+    std::span<int> S2 = std::span<int>{First, Last};   // 
expected-warning{{the two-parameter std::span or string_view construction is 
unsafe as it can introduce mismatch between buffer size and the bound 
information}}
+    std::span<int> S3 = std::span<int>(First, Last);   // 
expected-warning{{the two-parameter std::span or string_view construction is 
unsafe as it can introduce mismatch between buffer size and the bound 
information}}
+    std::span<int> S4 = std::span<int>{First, Last};   // 
expected-warning{{the two-parameter std::span or string_view construction is 
unsafe as it can introduce mismatch between buffer size and the bound 
information}}
+    std::span<int> S5 = std::span<int>(First, Last);   // 
expected-warning{{the two-parameter std::span or string_view construction is 
unsafe as it can introduce mismatch between buffer size and the bound 
information}}
+    std::span<int> S6 = {First, Last};                 // expected-warning{...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/180471
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to