llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Endre Fülöp (gamesh411) <details> <summary>Changes</summary> …d::inplace_merge The analyzer reports false positives in `std::stable_sort` and `std::inplace_merge` due to complex move semantics in `__uninitialized_construct_buf_dispatch::__ucr`. Add suppression for this STL internal function, following the pattern of existing suppressions for `std::basic_string` and `std::shared_ptr`. --- Full diff: https://github.com/llvm/llvm-project/pull/177804.diff 3 Files Affected: - (modified) clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp (+16) - (modified) clang/test/Analysis/Inputs/system-header-simulator-cxx-std-suppression.h (+35) - (modified) clang/test/Analysis/diagnostics/implicit-cxx-std-suppression.cpp (+10) ``````````diff diff --git a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp index 7df5fab0843ac..65e2ed5a28313 100644 --- a/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp +++ b/clang/lib/StaticAnalyzer/Core/BugReporterVisitors.cpp @@ -3305,6 +3305,22 @@ void LikelyFalsePositiveSuppressionBRVisitor::finalizeVisitor( } } + // Suppress false positives in std::stable_sort and std::inplace_merge. + // The analyzer reports uninitialized values in the + // __uninitialized_construct_buf_dispatch::__ucr method used by those + // algorithms due to complex move semantics with placement new. + if (const auto *FD = dyn_cast<FunctionDecl>(D)) { + if (FD->getName() == "__ucr") { + if (const auto *RD = dyn_cast<CXXRecordDecl>(FD->getParent())) { + if (RD->getName().starts_with( + "__uninitialized_construct_buf_dispatch")) { + BR.markInvalid(getTag(), nullptr); + return; + } + } + } + } + for (const LocationContext *LCtx = N->getLocationContext(); LCtx; LCtx = LCtx->getParent()) { const auto *MD = dyn_cast<CXXMethodDecl>(LCtx->getDecl()); diff --git a/clang/test/Analysis/Inputs/system-header-simulator-cxx-std-suppression.h b/clang/test/Analysis/Inputs/system-header-simulator-cxx-std-suppression.h index dc53af269c9c2..b7d61b2955f3c 100644 --- a/clang/test/Analysis/Inputs/system-header-simulator-cxx-std-suppression.h +++ b/clang/test/Analysis/Inputs/system-header-simulator-cxx-std-suppression.h @@ -142,5 +142,40 @@ shared_ptr<_Tp>::shared_ptr(nullptr_t) { } #endif // __has_feature(cxx_decltype) + +// Mock for __uninitialized_construct_buf_dispatch::__ucr suppression. +// std::stable_sort uses _Temporary_buffer which calls +// __uninitialized_construct_buf_dispatch::__ucr internally. +// The analyzer seems to lose track of initialization state in __ucr's complex +// move semantics, leading to false positives. +namespace __uninitialized_construct_buf_dispatch_impl { +template <bool> +struct __uninitialized_construct_buf_dispatch { + template <typename _Pointer, typename _ForwardIterator> + static _Pointer __ucr(_Pointer __first, _ForwardIterator __last) { + // Fake error trigger. + int z = 0; + z = 5/z; + return __first; + } +}; +} // namespace __uninitialized_construct_buf_dispatch_impl + +template <typename _RandomAccessIterator> +void stable_sort(_RandomAccessIterator __first, _RandomAccessIterator __last) { + // Calls __ucr internally, matching real STL implementation. + __uninitialized_construct_buf_dispatch_impl:: + __uninitialized_construct_buf_dispatch<false>::__ucr(__first, __last); } +template <typename _BidirectionalIterator> +void inplace_merge(_BidirectionalIterator __first, + _BidirectionalIterator __middle, + _BidirectionalIterator __last) { + // Also uses _Temporary_buffer which calls __ucr internally. + __uninitialized_construct_buf_dispatch_impl:: + __uninitialized_construct_buf_dispatch<false>::__ucr(__first, __middle); +} + +} // namespace std + diff --git a/clang/test/Analysis/diagnostics/implicit-cxx-std-suppression.cpp b/clang/test/Analysis/diagnostics/implicit-cxx-std-suppression.cpp index 35f8798c81ae1..f49d6f78c165a 100644 --- a/clang/test/Analysis/diagnostics/implicit-cxx-std-suppression.cpp +++ b/clang/test/Analysis/diagnostics/implicit-cxx-std-suppression.cpp @@ -37,3 +37,13 @@ void testSuppression_std_shared_pointer() { p = nullptr; // no-warning } + +void testSuppression_stable_sort() { + int arr[5]; + std::stable_sort(arr, arr + 5); // no-warning +} + +void testSuppression_inplace_merge() { + int arr[5]; + std::inplace_merge(arr, arr + 2, arr + 5); // no-warning +} `````````` </details> https://github.com/llvm/llvm-project/pull/177804 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
