[libcxx-commits] [libcxx] [libc++] Allow for hardening in multiple categories (PR #79859)

Will Hawkins via libcxx-commits libcxx-commits at lists.llvm.org
Mon Jan 29 19:55:45 PST 2024


https://github.com/hawkinsw updated https://github.com/llvm/llvm-project/pull/79859

>From c2443463e4f33894d3fe022e5b04ea396e5824ea Mon Sep 17 00:00:00 2001
From: Will Hawkins <hawkinsw at obs.cr>
Date: Mon, 29 Jan 2024 11:37:37 -0500
Subject: [PATCH 1/2] [libc++] Allow for hardening in multiple categories

Allow multiple categories for hardening assertions.
---
 libcxx/include/__config                      | 60 ++++++++++++++++++++
 libcxx/include/__iterator/counted_iterator.h |  2 +-
 2 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/libcxx/include/__config b/libcxx/include/__config
index 9fc608ee14320..36e0a98d11172 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -342,6 +342,15 @@ _LIBCPP_HARDENING_MODE_DEBUG
 // clang-format off
 // Fast hardening mode checks.
 
+// List all checks
+
+// VALID_INPUT_RANGE: Description of reason to use the check.
+// VALID_ELEMENT_ACCESS: Description of reason to use the check.
+// COMPATIBLE_ALLOCATOR: Description of reason to use the check.
+// PEDANTIC: Description of reason to use the check.
+// INTERNAL: Description of reason to use the check.
+// UNCATEGORIZED: Description of reason to use the check.
+
 #  if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST
 
 // Enabled checks.
@@ -362,6 +371,16 @@ _LIBCPP_HARDENING_MODE_DEBUG
 #    define _LIBCPP_ASSERT_INTERNAL(expression, message)                 _LIBCPP_ASSUME(expression)
 #    define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message)            _LIBCPP_ASSUME(expression)
 
+#    define VALID_INPUT_RANGE 1
+#    define VALID_PRECONDITIONS 1
+#    define VALID_ELEMENT_ACCESS 1
+#    define NON_NULL 0
+#    define OVERLAPPING_RANGES 0
+#    define COMPATIBLE_ALLOCATOR 0
+#    define PEDANTIC 0
+#    define INTERNAL 0
+#    define UNCATEGORIZED 0
+
 // Extensive hardening mode checks.
 
 #  elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_EXTENSIVE
@@ -381,6 +400,17 @@ _LIBCPP_HARDENING_MODE_DEBUG
 #    define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message)     _LIBCPP_ASSUME(expression)
 #    define _LIBCPP_ASSERT_INTERNAL(expression, message)                 _LIBCPP_ASSUME(expression)
 
+#    define VALID_INPUT_RANGE 1
+#    define VALID_ELEMENT_ACCESS 1
+#    define VALID_PRECONDITIONS 1
+#    define NON_NULL 1
+#    define OVERLAPPING_RANGES 1
+#    define COMPATIBLE_ALLOCATOR 1
+#    define PEDANTIC 1
+#    define UNCATEGORIZED 1
+
+#    define INTERNAL 0
+
 // Debug hardening mode checks.
 
 #  elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_DEBUG
@@ -399,6 +429,16 @@ _LIBCPP_HARDENING_MODE_DEBUG
 #    define _LIBCPP_ASSERT_INTERNAL(expression, message)                  _LIBCPP_ASSERT(expression, message)
 #    define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message)             _LIBCPP_ASSERT(expression, message)
 
+#    define VALID_INPUT_RANGE 1
+#    define VALID_ELEMENT_ACCESS 1
+#    define VALID_PRECONDITIONS 1
+#    define NON_NULL 1
+#    define OVERLAPPING_RANGES 1
+#    define COMPATIBLE_ALLOCATOR 1
+#    define PEDANTIC 1
+#    define INTERNAL 1
+#    define UNCATEGORIZED 1
+
 // Disable all checks if hardening is not enabled.
 
 #  else
@@ -417,7 +457,27 @@ _LIBCPP_HARDENING_MODE_DEBUG
 #    define _LIBCPP_ASSERT_INTERNAL(expression, message)                  _LIBCPP_ASSUME(expression)
 #    define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message)             _LIBCPP_ASSUME(expression)
 
+#    define VALID_INPUT_RANGE 0
+#    define VALID_ELEMENT_ACCESS 0
+#    define VALID_PRECONDITIONS 0
+#    define NON_NULL 0
+#    define OVERLAPPING_RANGES 0
+#    define COMPATIBLE_ALLOCATOR 0
+#    define PEDANTIC 0
+#    define INTERNAL 0
+#    define UNCATEGORIZED 0
+
 #  endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST
+
+#define _LIBCPP_ASSERT_P(reason, expression, message) \
+do {                                                  \
+  if (reason) {                                       \
+      _LIBCPP_ASSERT(expression, message);            \
+  } else {                                            \
+      _LIBCPP_ASSUME(expression);                     \
+  }                                                   \
+} while (0)
+
 // clang-format on
 
 // } HARDENING
diff --git a/libcxx/include/__iterator/counted_iterator.h b/libcxx/include/__iterator/counted_iterator.h
index 008c52fa87ce0..58f4317f0ba71 100644
--- a/libcxx/include/__iterator/counted_iterator.h
+++ b/libcxx/include/__iterator/counted_iterator.h
@@ -229,7 +229,7 @@ class counted_iterator
   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](iter_difference_t<_Iter> __n) const
     requires random_access_iterator<_Iter>
   {
-    _LIBCPP_ASSERT_VALID_ELEMENT_ACCESS(__n < __count_, "Subscript argument must be less than size.");
+    _LIBCPP_ASSERT_P(VALID_ELEMENT_ACCESS|VALID_PRECONDITIONS, __n < __count_, "Subscript argument must be less than size.");
     return __current_[__n];
   }
 

>From 5353b7fb9a8b1fefa9f139b8cc29209ef7f9d575 Mon Sep 17 00:00:00 2001
From: Will Hawkins <hawkinsw at obs.cr>
Date: Mon, 29 Jan 2024 22:55:15 -0500
Subject: [PATCH 2/2] fixup! [libc++] Allow for hardening in multiple
 categories

Revamp underlying plumbing.
---
 libcxx/include/__assert                      |  4 +
 libcxx/include/__config                      | 97 +++++++++++---------
 libcxx/include/__iterator/counted_iterator.h |  2 +-
 3 files changed, 60 insertions(+), 43 deletions(-)

diff --git a/libcxx/include/__assert b/libcxx/include/__assert
index eb862b5369b25..e37732c10e63b 100644
--- a/libcxx/include/__assert
+++ b/libcxx/include/__assert
@@ -34,4 +34,8 @@
 #  define _LIBCPP_ASSUME(expression) ((void)0)
 #endif
 
+#define _LIBCPP_ASSERT_OR_ASSUME(assert_or_assume, expression, message)                                                \
+  (__builtin_expect(static_cast<bool>(assert_or_assume), 0)                                                            \
+       ? _LIBCPP_ASSERT(expression, message) : _LIBCPP_ASSUME(expression))
+
 #endif // _LIBCPP___ASSERT
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 36e0a98d11172..00233f54044a6 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -344,12 +344,16 @@ _LIBCPP_HARDENING_MODE_DEBUG
 
 // List all checks
 
-// VALID_INPUT_RANGE: Description of reason to use the check.
-// VALID_ELEMENT_ACCESS: Description of reason to use the check.
-// COMPATIBLE_ALLOCATOR: Description of reason to use the check.
-// PEDANTIC: Description of reason to use the check.
-// INTERNAL: Description of reason to use the check.
-// UNCATEGORIZED: Description of reason to use the check.
+// _HD_VALID_INPUT_RANGE:    Description of reason to use the check.
+// _HD_VALID_ELEMENT_ACCESS: Description of reason to use the check.
+// _HD_VALID_PRECONDITIONS:  Description of reason to use the check.
+// _HD_NON_NULL:             Description of reason to use the check.
+// _HD_OVERLAPPING_RANGES:   Description of reason to use the check.
+// _HD_COMPATIBLE_ALLOCATOR: Description of reason to use the check.
+// _HD_PEDANTIC:             Description of reason to use the check.
+// _HD_SEMANTIC_REQUIREMENT: Description of reason to use the check.
+// _HD_INTERNAL:             Description of reason to use the check.
+// _HD_UNCATEGORIZED:        Description of reason to use the check.
 
 #  if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST
 
@@ -371,15 +375,18 @@ _LIBCPP_HARDENING_MODE_DEBUG
 #    define _LIBCPP_ASSERT_INTERNAL(expression, message)                 _LIBCPP_ASSUME(expression)
 #    define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message)            _LIBCPP_ASSUME(expression)
 
-#    define VALID_INPUT_RANGE 1
-#    define VALID_PRECONDITIONS 1
-#    define VALID_ELEMENT_ACCESS 1
-#    define NON_NULL 0
-#    define OVERLAPPING_RANGES 0
-#    define COMPATIBLE_ALLOCATOR 0
-#    define PEDANTIC 0
-#    define INTERNAL 0
-#    define UNCATEGORIZED 0
+// Enabled checks
+#    define _HD_VALID_INPUT_RANGE    true
+#    define _HD_VALID_ELEMENT_ACCESS true
+#    define _HD_VALID_PRECONDITIONS  true
+// Disabled checks
+#    define _HD_NON_NULL             false
+#    define _HD_OVERLAPPING_RANGES   false
+#    define _HD_COMPATIBLE_ALLOCATOR false
+#    define _HD_PEDANTIC             false
+#    define _HD_SEMANTIC_REQUIREMENT false
+#    define _HD_INTERNAL             false
+#    define _HD_UNCATEGORIZED        false
 
 // Extensive hardening mode checks.
 
@@ -400,16 +407,19 @@ _LIBCPP_HARDENING_MODE_DEBUG
 #    define _LIBCPP_ASSERT_SEMANTIC_REQUIREMENT(expression, message)     _LIBCPP_ASSUME(expression)
 #    define _LIBCPP_ASSERT_INTERNAL(expression, message)                 _LIBCPP_ASSUME(expression)
 
-#    define VALID_INPUT_RANGE 1
-#    define VALID_ELEMENT_ACCESS 1
-#    define VALID_PRECONDITIONS 1
-#    define NON_NULL 1
-#    define OVERLAPPING_RANGES 1
-#    define COMPATIBLE_ALLOCATOR 1
-#    define PEDANTIC 1
-#    define UNCATEGORIZED 1
+// Enabled checks.
+#    define _HD_VALID_INPUT_RANGE    true
+#    define _HD_VALID_ELEMENT_ACCESS true
+#    define _HD_VALID_PRECONDITIONS  true
+#    define _HD_NON_NULL             true
+#    define _HD_OVERLAPPING_RANGES   true
+#    define _HD_COMPATIBLE_ALLOCATOR true
+#    define _HD_PEDANTIC             true
+#    define _HD_UNCATEGORIZED        true
+// Disabled checks.
+#    define _HD_INTERNAL             false
+#    define _HD_SEMANTIC_REQUIREMENT false
 
-#    define INTERNAL 0
 
 // Debug hardening mode checks.
 
@@ -429,15 +439,16 @@ _LIBCPP_HARDENING_MODE_DEBUG
 #    define _LIBCPP_ASSERT_INTERNAL(expression, message)                  _LIBCPP_ASSERT(expression, message)
 #    define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message)             _LIBCPP_ASSERT(expression, message)
 
-#    define VALID_INPUT_RANGE 1
-#    define VALID_ELEMENT_ACCESS 1
-#    define VALID_PRECONDITIONS 1
-#    define NON_NULL 1
-#    define OVERLAPPING_RANGES 1
-#    define COMPATIBLE_ALLOCATOR 1
-#    define PEDANTIC 1
-#    define INTERNAL 1
-#    define UNCATEGORIZED 1
+#    define _HD_VALID_INPUT_RANGE    true
+#    define _HD_VALID_ELEMENT_ACCESS true
+#    define _HD_VALID_PRECONDITIONS  true
+#    define _HD_NON_NULL             true
+#    define _HD_OVERLAPPING_RANGES   true
+#    define _HD_COMPATIBLE_ALLOCATOR true
+#    define _HD_PEDANTIC             true
+#    define _HD_SEMANTIC_REQUIREMENT true
+#    define _HD_INTERNAL             true
+#    define _HD_UNCATEGORIZED        true
 
 // Disable all checks if hardening is not enabled.
 
@@ -457,15 +468,17 @@ _LIBCPP_HARDENING_MODE_DEBUG
 #    define _LIBCPP_ASSERT_INTERNAL(expression, message)                  _LIBCPP_ASSUME(expression)
 #    define _LIBCPP_ASSERT_UNCATEGORIZED(expression, message)             _LIBCPP_ASSUME(expression)
 
-#    define VALID_INPUT_RANGE 0
-#    define VALID_ELEMENT_ACCESS 0
-#    define VALID_PRECONDITIONS 0
-#    define NON_NULL 0
-#    define OVERLAPPING_RANGES 0
-#    define COMPATIBLE_ALLOCATOR 0
-#    define PEDANTIC 0
-#    define INTERNAL 0
-#    define UNCATEGORIZED 0
+// All checks disabled.
+#    define _HD_VALID_INPUT_RANGE    false
+#    define _HD_VALID_ELEMENT_ACCESS false
+#    define _HD_VALID_PRECONDITIONS  false
+#    define _HD_NON_NULL             false
+#    define _HD_OVERLAPPING_RANGES   false
+#    define _HD_COMPATIBLE_ALLOCATOR false
+#    define _HD_PEDANTIC             false
+#    define _HD_SEMANTIC_REQUIREMENT false
+#    define _HD_INTERNAL             false
+#    define _HD_UNCATEGORIZED        false
 
 #  endif // _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST
 
diff --git a/libcxx/include/__iterator/counted_iterator.h b/libcxx/include/__iterator/counted_iterator.h
index 58f4317f0ba71..8f9bc1a9d419b 100644
--- a/libcxx/include/__iterator/counted_iterator.h
+++ b/libcxx/include/__iterator/counted_iterator.h
@@ -229,7 +229,7 @@ class counted_iterator
   _LIBCPP_HIDE_FROM_ABI constexpr decltype(auto) operator[](iter_difference_t<_Iter> __n) const
     requires random_access_iterator<_Iter>
   {
-    _LIBCPP_ASSERT_P(VALID_ELEMENT_ACCESS|VALID_PRECONDITIONS, __n < __count_, "Subscript argument must be less than size.");
+    _LIBCPP_ASSERT_P(_HD_VALID_ELEMENT_ACCESS|_HD_VALID_PRECONDITIONS, __n < __count_, "Subscript argument must be less than size.");
     return __current_[__n];
   }
 



More information about the libcxx-commits mailing list