[clang] 0dcb0ac - [-Wunsafe-buffer-usage] Fix false positives in warning againt 2-parameter std::span constructor (#115797)
via cfe-commits
cfe-commits at lists.llvm.org
Wed Nov 13 13:08:55 PST 2024
Author: Malavika Samak
Date: 2024-11-13T13:08:52-08:00
New Revision: 0dcb0acf8265e1486f4f3715cef01987af1391cd
URL: https://github.com/llvm/llvm-project/commit/0dcb0acf8265e1486f4f3715cef01987af1391cd
DIFF: https://github.com/llvm/llvm-project/commit/0dcb0acf8265e1486f4f3715cef01987af1391cd.diff
LOG: [-Wunsafe-buffer-usage] Fix false positives in warning againt 2-parameter std::span constructor (#115797)
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)
Co-authored-by: MalavikaSamak <malavika2 at apple.com>
Added:
Modified:
clang/lib/Analysis/UnsafeBufferUsage.cpp
clang/test/SemaCXX/warn-unsafe-buffer-usage-in-container-span-construct.cpp
Removed:
################################################################################
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index b683826503c74c..881756b9b5f9b4 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -366,6 +366,7 @@ isInUnspecifiedUntypedContext(internal::Matcher<Stmt> InnerMatcher) {
// 4. `std::span<T>{a, n}`, where `a` is of an array-of-T with constant size
// `n`
// 5. `std::span<T>{any, 0}`
+// 6. `std::span<T>{std::addressof(...), 1}`
AST_MATCHER(CXXConstructExpr, isSafeSpanTwoParamConstruct) {
assert(Node.getNumArgs() == 2 &&
"expecting a two-parameter std::span constructor");
@@ -410,6 +411,15 @@ 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
More information about the cfe-commits
mailing list