[clang-tools-extra] [libc++] Add assertions for potential OOB reads in std::nth_element (PR #67023)

2023-10-18 Thread Daniel Kutenin via cfe-commits

https://github.com/danlark1 updated 
https://github.com/llvm/llvm-project/pull/67023

>From 059bbfab50592026ce2785c5f7d98eaf5c9f8bd6 Mon Sep 17 00:00:00 2001
From: Daniel Kutenin 
Date: Thu, 21 Sep 2023 14:55:11 +0100
Subject: [PATCH 1/7] Add bound checking in nth_element

---
 libcxx/include/__algorithm/nth_element.h | 28 +++-
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/libcxx/include/__algorithm/nth_element.h 
b/libcxx/include/__algorithm/nth_element.h
index dbacf58f9ecdbc4..37e43ab0db8ca4f 100644
--- a/libcxx/include/__algorithm/nth_element.h
+++ b/libcxx/include/__algorithm/nth_element.h
@@ -116,10 +116,18 @@ __nth_element(_RandomAccessIterator __first, 
_RandomAccessIterator __nth, _Rando
 return;
 }
 while (true) {
-while (!__comp(*__first, *__i))
+while (!__comp(*__first, *__i)) {
 ++__i;
-while (__comp(*__first, *--__j))
-;
+_LIBCPP_ASSERT_UNCATEGORIZED(
+__i != __last,
+"Would read out of bounds, does your comparator 
satisfy the strict-weak ordering requirement?");
+}
+do {
+_LIBCPP_ASSERT_UNCATEGORIZED(
+__j != __first,
+"Would read out of bounds, does your comparator 
satisfy the strict-weak ordering requirement?");
+--__j;
+} while (__comp(*__first, *__j));
 if (__i >= __j)
 break;
 _Ops::iter_swap(__i, __j);
@@ -146,11 +154,19 @@ __nth_element(_RandomAccessIterator __first, 
_RandomAccessIterator __nth, _Rando
 while (true)
 {
 // __m still guards upward moving __i
-while (__comp(*__i, *__m))
+while (__comp(*__i, *__m)) {
 ++__i;
+_LIBCPP_ASSERT_UNCATEGORIZED(
+__i != __last,
+"Would read out of bounds, does your comparator 
satisfy the strict-weak ordering requirement?");
+}
 // It is now known that a guard exists for downward moving __j
-while (!__comp(*--__j, *__m))
-;
+do {
+_LIBCPP_ASSERT_UNCATEGORIZED(
+__j != __first,
+"Would read out of bounds, does your comparator 
satisfy the strict-weak ordering requirement?");
+--__j;
+} while (!__comp(*__j, *__m));
 if (__i >= __j)
 break;
 _Ops::iter_swap(__i, __j);

>From 8e128c3ce6d8dc8afb94ba2465a2585fe3b8525a Mon Sep 17 00:00:00 2001
From: Daniel Kutenin 
Date: Thu, 21 Sep 2023 15:22:18 +0100
Subject: [PATCH 2/7] Update nth_element out of bound test

---
 .../assert.sort.invalid_comparator.pass.cpp   | 77 +++
 1 file changed, 61 insertions(+), 16 deletions(-)

diff --git 
a/libcxx/test/libcxx/algorithms/alg.sorting/assert.sort.invalid_comparator.pass.cpp
 
b/libcxx/test/libcxx/algorithms/alg.sorting/assert.sort.invalid_comparator.pass.cpp
index e5e417fe7bda2d4..b02ae2118ec5f47 100644
--- 
a/libcxx/test/libcxx/algorithms/alg.sorting/assert.sort.invalid_comparator.pass.cpp
+++ 
b/libcxx/test/libcxx/algorithms/alg.sorting/assert.sort.invalid_comparator.pass.cpp
@@ -50,27 +50,37 @@
 #include "bad_comparator_values.h"
 #include "check_assertion.h"
 
-void check_oob_sort_read() {
-std::map> comparison_results; // 
terrible for performance, but really convenient
-for (auto line : std::views::split(DATA, '\n') | 
std::views::filter([](auto const& line) { return !line.empty(); })) {
-auto values = std::views::split(line, ' ');
-auto it = values.begin();
-std::size_t left = std::stol(std::string((*it).data(), (*it).size()));
-it = std::next(it);
-std::size_t right = std::stol(std::string((*it).data(), (*it).size()));
-it = std::next(it);
-bool result = static_cast(std::stol(std::string((*it).data(), 
(*it).size(;
-comparison_results[left][right] = result;
-}
-auto predicate = [&](std::size_t* left, std::size_t* right) {
+class ComparisonResults {
+public:
+ComparisonResults(std::string_view data) {
+for (auto line : std::views::split(data, '\n') | 
std::views::filter([](auto const& line) { return !line.empty(); })) {
+auto values = std::views::split(line, ' ');
+auto it = values.begin();
+std::size_t left = std::stol(std::string((*it).data(), 
(*it).size()));
+it = std::next(it);
+std::size_t right = std::stol(std::string((*it).data(), 
(*it).size()));
+it = std::next(it);
+ 

[clang] [libc++] Add assertions for potential OOB reads in std::nth_element (PR #67023)

2023-10-18 Thread Daniel Kutenin via cfe-commits

https://github.com/danlark1 updated 
https://github.com/llvm/llvm-project/pull/67023

>From 059bbfab50592026ce2785c5f7d98eaf5c9f8bd6 Mon Sep 17 00:00:00 2001
From: Daniel Kutenin 
Date: Thu, 21 Sep 2023 14:55:11 +0100
Subject: [PATCH 1/7] Add bound checking in nth_element

---
 libcxx/include/__algorithm/nth_element.h | 28 +++-
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/libcxx/include/__algorithm/nth_element.h 
b/libcxx/include/__algorithm/nth_element.h
index dbacf58f9ecdbc4..37e43ab0db8ca4f 100644
--- a/libcxx/include/__algorithm/nth_element.h
+++ b/libcxx/include/__algorithm/nth_element.h
@@ -116,10 +116,18 @@ __nth_element(_RandomAccessIterator __first, 
_RandomAccessIterator __nth, _Rando
 return;
 }
 while (true) {
-while (!__comp(*__first, *__i))
+while (!__comp(*__first, *__i)) {
 ++__i;
-while (__comp(*__first, *--__j))
-;
+_LIBCPP_ASSERT_UNCATEGORIZED(
+__i != __last,
+"Would read out of bounds, does your comparator 
satisfy the strict-weak ordering requirement?");
+}
+do {
+_LIBCPP_ASSERT_UNCATEGORIZED(
+__j != __first,
+"Would read out of bounds, does your comparator 
satisfy the strict-weak ordering requirement?");
+--__j;
+} while (__comp(*__first, *__j));
 if (__i >= __j)
 break;
 _Ops::iter_swap(__i, __j);
@@ -146,11 +154,19 @@ __nth_element(_RandomAccessIterator __first, 
_RandomAccessIterator __nth, _Rando
 while (true)
 {
 // __m still guards upward moving __i
-while (__comp(*__i, *__m))
+while (__comp(*__i, *__m)) {
 ++__i;
+_LIBCPP_ASSERT_UNCATEGORIZED(
+__i != __last,
+"Would read out of bounds, does your comparator 
satisfy the strict-weak ordering requirement?");
+}
 // It is now known that a guard exists for downward moving __j
-while (!__comp(*--__j, *__m))
-;
+do {
+_LIBCPP_ASSERT_UNCATEGORIZED(
+__j != __first,
+"Would read out of bounds, does your comparator 
satisfy the strict-weak ordering requirement?");
+--__j;
+} while (!__comp(*__j, *__m));
 if (__i >= __j)
 break;
 _Ops::iter_swap(__i, __j);

>From 8e128c3ce6d8dc8afb94ba2465a2585fe3b8525a Mon Sep 17 00:00:00 2001
From: Daniel Kutenin 
Date: Thu, 21 Sep 2023 15:22:18 +0100
Subject: [PATCH 2/7] Update nth_element out of bound test

---
 .../assert.sort.invalid_comparator.pass.cpp   | 77 +++
 1 file changed, 61 insertions(+), 16 deletions(-)

diff --git 
a/libcxx/test/libcxx/algorithms/alg.sorting/assert.sort.invalid_comparator.pass.cpp
 
b/libcxx/test/libcxx/algorithms/alg.sorting/assert.sort.invalid_comparator.pass.cpp
index e5e417fe7bda2d4..b02ae2118ec5f47 100644
--- 
a/libcxx/test/libcxx/algorithms/alg.sorting/assert.sort.invalid_comparator.pass.cpp
+++ 
b/libcxx/test/libcxx/algorithms/alg.sorting/assert.sort.invalid_comparator.pass.cpp
@@ -50,27 +50,37 @@
 #include "bad_comparator_values.h"
 #include "check_assertion.h"
 
-void check_oob_sort_read() {
-std::map> comparison_results; // 
terrible for performance, but really convenient
-for (auto line : std::views::split(DATA, '\n') | 
std::views::filter([](auto const& line) { return !line.empty(); })) {
-auto values = std::views::split(line, ' ');
-auto it = values.begin();
-std::size_t left = std::stol(std::string((*it).data(), (*it).size()));
-it = std::next(it);
-std::size_t right = std::stol(std::string((*it).data(), (*it).size()));
-it = std::next(it);
-bool result = static_cast(std::stol(std::string((*it).data(), 
(*it).size(;
-comparison_results[left][right] = result;
-}
-auto predicate = [&](std::size_t* left, std::size_t* right) {
+class ComparisonResults {
+public:
+ComparisonResults(std::string_view data) {
+for (auto line : std::views::split(data, '\n') | 
std::views::filter([](auto const& line) { return !line.empty(); })) {
+auto values = std::views::split(line, ' ');
+auto it = values.begin();
+std::size_t left = std::stol(std::string((*it).data(), 
(*it).size()));
+it = std::next(it);
+std::size_t right = std::stol(std::string((*it).data(), 
(*it).size()));
+it = std::next(it);
+ 

[clang-tools-extra] [libc++] Add assertions for potential OOB reads in std::nth_element (PR #67023)

2023-10-18 Thread Daniel Kutenin via cfe-commits

danlark1 wrote:

@ldionne, CI is green, please, merge

Thanks for the feedback to everyone!

https://github.com/llvm/llvm-project/pull/67023
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang] [libc++] Add assertions for potential OOB reads in std::nth_element (PR #67023)

2023-10-18 Thread Daniel Kutenin via cfe-commits

danlark1 wrote:

@ldionne, CI is green, please, merge

Thanks for the feedback to everyone!

https://github.com/llvm/llvm-project/pull/67023
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [libc++] Add assertions for potential OOB reads in std::nth_element (PR #67023)

2023-10-16 Thread Daniel Kutenin via cfe-commits

https://github.com/danlark1 updated 
https://github.com/llvm/llvm-project/pull/67023

>From 059bbfab50592026ce2785c5f7d98eaf5c9f8bd6 Mon Sep 17 00:00:00 2001
From: Daniel Kutenin 
Date: Thu, 21 Sep 2023 14:55:11 +0100
Subject: [PATCH 1/6] Add bound checking in nth_element

---
 libcxx/include/__algorithm/nth_element.h | 28 +++-
 1 file changed, 22 insertions(+), 6 deletions(-)

diff --git a/libcxx/include/__algorithm/nth_element.h 
b/libcxx/include/__algorithm/nth_element.h
index dbacf58f9ecdbc4..37e43ab0db8ca4f 100644
--- a/libcxx/include/__algorithm/nth_element.h
+++ b/libcxx/include/__algorithm/nth_element.h
@@ -116,10 +116,18 @@ __nth_element(_RandomAccessIterator __first, 
_RandomAccessIterator __nth, _Rando
 return;
 }
 while (true) {
-while (!__comp(*__first, *__i))
+while (!__comp(*__first, *__i)) {
 ++__i;
-while (__comp(*__first, *--__j))
-;
+_LIBCPP_ASSERT_UNCATEGORIZED(
+__i != __last,
+"Would read out of bounds, does your comparator 
satisfy the strict-weak ordering requirement?");
+}
+do {
+_LIBCPP_ASSERT_UNCATEGORIZED(
+__j != __first,
+"Would read out of bounds, does your comparator 
satisfy the strict-weak ordering requirement?");
+--__j;
+} while (__comp(*__first, *__j));
 if (__i >= __j)
 break;
 _Ops::iter_swap(__i, __j);
@@ -146,11 +154,19 @@ __nth_element(_RandomAccessIterator __first, 
_RandomAccessIterator __nth, _Rando
 while (true)
 {
 // __m still guards upward moving __i
-while (__comp(*__i, *__m))
+while (__comp(*__i, *__m)) {
 ++__i;
+_LIBCPP_ASSERT_UNCATEGORIZED(
+__i != __last,
+"Would read out of bounds, does your comparator 
satisfy the strict-weak ordering requirement?");
+}
 // It is now known that a guard exists for downward moving __j
-while (!__comp(*--__j, *__m))
-;
+do {
+_LIBCPP_ASSERT_UNCATEGORIZED(
+__j != __first,
+"Would read out of bounds, does your comparator 
satisfy the strict-weak ordering requirement?");
+--__j;
+} while (!__comp(*__j, *__m));
 if (__i >= __j)
 break;
 _Ops::iter_swap(__i, __j);

>From 8e128c3ce6d8dc8afb94ba2465a2585fe3b8525a Mon Sep 17 00:00:00 2001
From: Daniel Kutenin 
Date: Thu, 21 Sep 2023 15:22:18 +0100
Subject: [PATCH 2/6] Update nth_element out of bound test

---
 .../assert.sort.invalid_comparator.pass.cpp   | 77 +++
 1 file changed, 61 insertions(+), 16 deletions(-)

diff --git 
a/libcxx/test/libcxx/algorithms/alg.sorting/assert.sort.invalid_comparator.pass.cpp
 
b/libcxx/test/libcxx/algorithms/alg.sorting/assert.sort.invalid_comparator.pass.cpp
index e5e417fe7bda2d4..b02ae2118ec5f47 100644
--- 
a/libcxx/test/libcxx/algorithms/alg.sorting/assert.sort.invalid_comparator.pass.cpp
+++ 
b/libcxx/test/libcxx/algorithms/alg.sorting/assert.sort.invalid_comparator.pass.cpp
@@ -50,27 +50,37 @@
 #include "bad_comparator_values.h"
 #include "check_assertion.h"
 
-void check_oob_sort_read() {
-std::map> comparison_results; // 
terrible for performance, but really convenient
-for (auto line : std::views::split(DATA, '\n') | 
std::views::filter([](auto const& line) { return !line.empty(); })) {
-auto values = std::views::split(line, ' ');
-auto it = values.begin();
-std::size_t left = std::stol(std::string((*it).data(), (*it).size()));
-it = std::next(it);
-std::size_t right = std::stol(std::string((*it).data(), (*it).size()));
-it = std::next(it);
-bool result = static_cast(std::stol(std::string((*it).data(), 
(*it).size(;
-comparison_results[left][right] = result;
-}
-auto predicate = [&](std::size_t* left, std::size_t* right) {
+class ComparisonResults {
+public:
+ComparisonResults(std::string_view data) {
+for (auto line : std::views::split(data, '\n') | 
std::views::filter([](auto const& line) { return !line.empty(); })) {
+auto values = std::views::split(line, ' ');
+auto it = values.begin();
+std::size_t left = std::stol(std::string((*it).data(), 
(*it).size()));
+it = std::next(it);
+std::size_t right = std::stol(std::string((*it).data(), 
(*it).size()));
+it = std::next(it);
+ 

[clang] [libc++] Add assertions for potential OOB reads in std::nth_element (PR #67023)

2023-10-16 Thread Daniel Kutenin via cfe-commits

danlark1 wrote:

>Also @danlark1 if you rebase onto main the issues with macOS in the CI should 
>be fixed now.

@ldionne, Done

https://github.com/llvm/llvm-project/pull/67023
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits


[clang-tools-extra] [libc++] Add assertions for potential OOB reads in std::nth_element (PR #67023)

2023-10-16 Thread Daniel Kutenin via cfe-commits

danlark1 wrote:

>Also @danlark1 if you rebase onto main the issues with macOS in the CI should 
>be fixed now.

@ldionne, Done

https://github.com/llvm/llvm-project/pull/67023
___
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits