https://github.com/malavikasamak updated https://github.com/llvm/llvm-project/pull/115797
>From a60c18973c0ea5b59c7c5f38813083e862f70e6e Mon Sep 17 00:00:00 2001 From: MalavikaSamak <malavi...@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 <malavi...@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(); } } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits