https://github.com/pjalwadi updated https://github.com/llvm/llvm-project/pull/180471
>From f2ffc5be5753f9061015d02ec0c14ab0b1ae17f6 Mon Sep 17 00:00:00 2001 From: prajwal jalwadi <[email protected]> Date: Mon, 9 Feb 2026 09:50:37 +0530 Subject: [PATCH] "[Clang][UnsafeBufferUsage] Warn about two-arg string_view constructors" -m "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." --- clang/docs/ReleaseNotes.rst | 3 + .../clang/Basic/DiagnosticSemaKinds.td | 2 +- clang/lib/Analysis/UnsafeBufferUsage.cpp | 3 +- .../warn-unsafe-buffer-usage-field-attr.cpp | 2 +- ...ffer-usage-in-container-span-construct.cpp | 124 +++++++++--------- .../warn-unsafe-buffer-usage-string-view.cpp | 20 +++ 6 files changed, 89 insertions(+), 65 deletions(-) create mode 100644 clang/test/SemaCXX/warn-unsafe-buffer-usage-string-view.cpp 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{{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>{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}} + auto S8 = 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}} + const auto &S9 = 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}} + auto &&S10 = 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}} + + if (auto X = std::span<int>{First, Last}; 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(First, Last); // function return is fine @@ -178,15 +178,15 @@ namespace construct_wt_begin_end { void foo(const T &, const T &&, T); std::span<int> warnTemp(It &First, It &Last) { - foo(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::move(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>{First, Last}); // 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>{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::move(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>{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> Arr[1] = {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> Arr[1] = {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}} - if (std::span<int>{First, Last}.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>{First, Last}.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>{First, Last}; // 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>{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}} } } // namespace construct_wt_begin_end @@ -211,20 +211,20 @@ namespace test_alloc_size_attr { } void unsafe(int x, int y) { - std::span<char>{(char *)my_alloc(10), 11}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} - std::span<char>{(char *)my_alloc(x * y), x + y}; // 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>{(int *)my_alloc(x), x}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} - std::span<char>{(char *)my_alloc2(x, y), x + y}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} + std::span<char>{(char *)my_alloc(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}} + std::span<char>{(char *)my_alloc(x * y), x + 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}} + std::span<int>{(int *)my_alloc(x), 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}} + std::span<char>{(char *)my_alloc2(x, y), x + 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}} } void unsupport(int x, int y, int z) { // Casting to `T*` where sizeof(T) > 1 is not supported yet: - std::span<int>{(int *)my_alloc2(x, y), x * y}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} - std::span<long>{(long *)my_alloc(10 * sizeof(long)), 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<long>{(long *)my_alloc2(x, sizeof(long)), x}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} - std::span<long>{(long *)my_alloc2(x, sizeof(long)), x}; // 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>{(int *)my_alloc2(x, y), x * 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}} + std::span<long>{(long *)my_alloc(10 * sizeof(long)), 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<long>{(long *)my_alloc2(x, sizeof(long)), 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}} + std::span<long>{(long *)my_alloc2(x, sizeof(long)), 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}} // The expression is too complicated: - std::span<char>{(char *)my_alloc(x + y + z), z + y + x}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} + std::span<char>{(char *)my_alloc(x + y + z), z + y + 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}} } } @@ -255,14 +255,14 @@ struct HoldsStdSpanAndInitializedInCtor { std::span<char> Span{Ptr, Size}; // no-warning (this code is unreachable) HoldsStdSpanAndInitializedInCtor(char* P, unsigned S) - : Span(P, S) // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} + : Span(P, S) // 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}} {} }; struct HoldsStdSpanAndNotInitializedInCtor { char* Ptr; unsigned Size; - std::span<char> Span{Ptr, Size}; // expected-warning{{the two-parameter std::span construction is unsafe as it can introduce mismatch between buffer size and the bound information}} + std::span<char> Span{Ptr, Size}; // 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}} HoldsStdSpanAndNotInitializedInCtor(char* P, unsigned S) : Ptr(P), Size(S) @@ -283,12 +283,12 @@ namespace test_begin_end { void unsafe_cases(std::span<int> Sp, std::array<int, 10> Arr, std::string Str, std::initializer_list<Object> Il, Object Obj) { - std::span<int>{Obj.begin(), Obj.end()}; // 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>{Sp.end(), Sp.begin()}; // 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>{Sp.begin(), Arr.end()}; // 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>{Obj.begin(), Obj.end()}; // 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>{Sp.end(), Sp.begin()}; // 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>{Sp.begin(), Arr.end()}; // 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}} } void unsupport_cases(std::array<Object, 10> Arr) { - std::span<int>{Arr[0].begin(), Arr[0].end()}; // 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[0].begin(), Arr[0].end()}; // 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}} } } diff --git a/clang/test/SemaCXX/warn-unsafe-buffer-usage-string-view.cpp b/clang/test/SemaCXX/warn-unsafe-buffer-usage-string-view.cpp new file mode 100644 index 0000000000000..0f652c7f36e17 --- /dev/null +++ b/clang/test/SemaCXX/warn-unsafe-buffer-usage-string-view.cpp @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -std=c++20 -Wunsafe-buffer-usage -verify %s + +namespace std { + template <typename T> + class basic_string_view { + public: + basic_string_view(T*, int); + basic_string_view(T*); + }; + + using string_view = basic_string_view<char>; +} + +void test(char *ptr, int size) { + // CASE 1: Unsafe (Ptr + Size) -> Should Warn + std::string_view sv1(ptr, size); // expected-warning{{the two-parameter std::span or string_view construction is unsafe}} + + // CASE 2: Safe (Ptr only) -> Should NOT Warn + std::string_view sv2(ptr); +} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
