[libcxx-commits] [libcxx] c87c891 - [libc++] Audit all uses of _LIBCPP_ASSERT and _LIBCPP_DEBUG_ASSERT

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Thu Mar 24 10:13:55 PDT 2022


Author: Louis Dionne
Date: 2022-03-24T13:13:21-04:00
New Revision: c87c8917e3662532f0aa75a91caea857c093f8f4

URL: https://github.com/llvm/llvm-project/commit/c87c8917e3662532f0aa75a91caea857c093f8f4
DIFF: https://github.com/llvm/llvm-project/commit/c87c8917e3662532f0aa75a91caea857c093f8f4.diff

LOG: [libc++] Audit all uses of _LIBCPP_ASSERT and _LIBCPP_DEBUG_ASSERT

I audited all uses of _LIBCPP_ASSERT to make sure that we only used it
for "basic assertions", i.e. assertions with constant-time conditions.
I also audited all uses of _LIBCPP_DEBUG_ASSERT to make sure we used it
only for debug-mode assertions, and in one case had to change for
_LIBCPP_ASSERT instead.

As a fly-by, I also changed a couple of tests against nullptr or 0 to
be more explicit.

After this patch, all uses of _LIBCPP_ASSERT should be with constant-time
conditions, and all uses of _LIBCPP_DEBUG_ASSERT should be with conditions
that we only want to check when the debug mode is enabled.

Differential Revision: https://reviews.llvm.org/D122395

Added: 
    

Modified: 
    libcxx/include/__hash_table
    libcxx/include/__memory/construct_at.h
    libcxx/include/list
    libcxx/include/unordered_set
    libcxx/src/filesystem/filesystem_common.h

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__hash_table b/libcxx/include/__hash_table
index f4e3a1e5bb7c3..d180187a73587 100644
--- a/libcxx/include/__hash_table
+++ b/libcxx/include/__hash_table
@@ -2478,8 +2478,8 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::erase(const_iterator __p)
     _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
                          "unordered container erase(iterator) called with an iterator not"
                          " referring to this container");
-    _LIBCPP_DEBUG_ASSERT(__p != end(),
-                         "unordered container erase(iterator) called with a non-dereferenceable iterator");
+    _LIBCPP_ASSERT(__p != end(),
+                   "unordered container erase(iterator) called with a non-dereferenceable iterator");
 #if _LIBCPP_DEBUG_LEVEL == 2
     iterator __r(__np, this);
 #else

diff  --git a/libcxx/include/__memory/construct_at.h b/libcxx/include/__memory/construct_at.h
index 8a7bf40d7f716..bcca0fdb18edc 100644
--- a/libcxx/include/__memory/construct_at.h
+++ b/libcxx/include/__memory/construct_at.h
@@ -34,7 +34,7 @@ template<class _Tp, class ..._Args, class = decltype(
 )>
 _LIBCPP_HIDE_FROM_ABI
 constexpr _Tp* construct_at(_Tp* __location, _Args&& ...__args) {
-    _LIBCPP_ASSERT(__location, "null pointer given to construct_at");
+    _LIBCPP_ASSERT(__location != nullptr, "null pointer given to construct_at");
     return ::new (_VSTD::__voidify(*__location)) _Tp(_VSTD::forward<_Args>(__args)...);
 }
 
@@ -52,7 +52,7 @@ _ForwardIterator __destroy(_ForwardIterator, _ForwardIterator);
 template <class _Tp, typename enable_if<!is_array<_Tp>::value, int>::type = 0>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
 void __destroy_at(_Tp* __loc) {
-    _LIBCPP_ASSERT(__loc, "null pointer given to destroy_at");
+    _LIBCPP_ASSERT(__loc != nullptr, "null pointer given to destroy_at");
     __loc->~_Tp();
 }
 
@@ -60,7 +60,7 @@ void __destroy_at(_Tp* __loc) {
 template <class _Tp, typename enable_if<is_array<_Tp>::value, int>::type = 0>
 _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX17
 void __destroy_at(_Tp* __loc) {
-    _LIBCPP_ASSERT(__loc, "null pointer given to destroy_at");
+    _LIBCPP_ASSERT(__loc != nullptr, "null pointer given to destroy_at");
     _VSTD::__destroy(_VSTD::begin(*__loc), _VSTD::end(*__loc));
 }
 #endif

diff  --git a/libcxx/include/list b/libcxx/include/list
index 5f32b13608f55..58efc0426a538 100644
--- a/libcxx/include/list
+++ b/libcxx/include/list
@@ -2020,6 +2020,17 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __i)
     }
 }
 
+template <class _Iterator>
+_LIBCPP_HIDE_FROM_ABI
+bool __iterator_in_range(_Iterator __first, _Iterator __last, _Iterator __it) {
+    for (_Iterator __p = __first; __p != __last; ++__p) {
+        if (__p == __it) {
+            return true;
+        }
+    }
+    return false;
+}
+
 template <class _Tp, class _Alloc>
 void
 list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, const_iterator __l)
@@ -2030,16 +2041,10 @@ list<_Tp, _Alloc>::splice(const_iterator __p, list& __c, const_iterator __f, con
         "list::splice(iterator, list, iterator, iterator) called with second iterator not referring to the list argument");
     _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__l)) == _VSTD::addressof(__c),
         "list::splice(iterator, list, iterator, iterator) called with third iterator not referring to the list argument");
+    _LIBCPP_DEBUG_ASSERT(this != std::addressof(__c) || !std::__iterator_in_range(__f, __l, __p),
+        "list::splice(iterator, list, iterator, iterator)"
+        " called with the first iterator within the range of the second and third iterators");
 
-#if _LIBCPP_DEBUG_LEVEL == 2
-    if (this == _VSTD::addressof(__c))
-    {
-        for (const_iterator __i = __f; __i != __l; ++__i)
-            _LIBCPP_DEBUG_ASSERT(__i != __p,
-                "list::splice(iterator, list, iterator, iterator)"
-                " called with the first iterator within the range of the second and third iterators");
-    }
-#endif
     if (__f != __l)
     {
         __link_pointer __first = __f.__ptr_;

diff  --git a/libcxx/include/unordered_set b/libcxx/include/unordered_set
index 2f902cc79341d..4dd1b8c6a0943 100644
--- a/libcxx/include/unordered_set
+++ b/libcxx/include/unordered_set
@@ -639,36 +639,27 @@ public:
         pair<iterator, bool> emplace(_Args&&... __args)
             {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...);}
     template <class... _Args>
-        _LIBCPP_INLINE_VISIBILITY
-#if _LIBCPP_DEBUG_LEVEL == 2
-        iterator emplace_hint(const_iterator __p, _Args&&... __args)
-        {
-            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                "unordered_set::emplace_hint(const_iterator, args...) called with an iterator not"
-                " referring to this unordered_set");
-            return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;
-        }
-#else
-        iterator emplace_hint(const_iterator, _Args&&... __args)
-            {return __table_.__emplace_unique(_VSTD::forward<_Args>(__args)...).first;}
-#endif
+    _LIBCPP_INLINE_VISIBILITY
+    iterator emplace_hint(const_iterator __p, _Args&&... __args) {
+        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this,
+            "unordered_set::emplace_hint(const_iterator, args...) called with an iterator not"
+            " referring to this unordered_set");
+        (void)__p;
+        return __table_.__emplace_unique(std::forward<_Args>(__args)...).first;
+    }
 
     _LIBCPP_INLINE_VISIBILITY
     pair<iterator, bool> insert(value_type&& __x)
         {return __table_.__insert_unique(_VSTD::move(__x));}
     _LIBCPP_INLINE_VISIBILITY
-#if _LIBCPP_DEBUG_LEVEL == 2
-    iterator insert(const_iterator __p, value_type&& __x)
-        {
-            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                "unordered_set::insert(const_iterator, value_type&&) called with an iterator not"
-                " referring to this unordered_set");
-            return insert(_VSTD::move(__x)).first;
-        }
-#else
-    iterator insert(const_iterator, value_type&& __x)
-        {return insert(_VSTD::move(__x)).first;}
-#endif
+    iterator insert(const_iterator __p, value_type&& __x) {
+        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this,
+            "unordered_set::insert(const_iterator, value_type&&) called with an iterator not"
+            " referring to this unordered_set");
+        (void)__p;
+        return insert(std::move(__x)).first;
+    }
+
     _LIBCPP_INLINE_VISIBILITY
     void insert(initializer_list<value_type> __il)
         {insert(__il.begin(), __il.end());}
@@ -678,18 +669,13 @@ public:
         {return __table_.__insert_unique(__x);}
 
     _LIBCPP_INLINE_VISIBILITY
-#if _LIBCPP_DEBUG_LEVEL == 2
-    iterator insert(const_iterator __p, const value_type& __x)
-        {
-            _LIBCPP_ASSERT(__get_const_db()->__find_c_from_i(_VSTD::addressof(__p)) == this,
-                "unordered_set::insert(const_iterator, const value_type&) called with an iterator not"
-                " referring to this unordered_set");
-            return insert(__x).first;
-        }
-#else
-    iterator insert(const_iterator, const value_type& __x)
-        {return insert(__x).first;}
-#endif
+    iterator insert(const_iterator __p, const value_type& __x) {
+        _LIBCPP_DEBUG_ASSERT(__get_const_db()->__find_c_from_i(std::addressof(__p)) == this,
+            "unordered_set::insert(const_iterator, const value_type&) called with an iterator not"
+            " referring to this unordered_set");
+        (void)__p;
+        return insert(__x).first;
+    }
     template <class _InputIterator>
         _LIBCPP_INLINE_VISIBILITY
         void insert(_InputIterator __first, _InputIterator __last);

diff  --git a/libcxx/src/filesystem/filesystem_common.h b/libcxx/src/filesystem/filesystem_common.h
index c9bc998007a66..7b2b10adeb7eb 100644
--- a/libcxx/src/filesystem/filesystem_common.h
+++ b/libcxx/src/filesystem/filesystem_common.h
@@ -111,7 +111,7 @@ format_string(const char* msg, ...) {
 }
 
 error_code capture_errno() {
-  _LIBCPP_ASSERT(errno, "Expected errno to be non-zero");
+  _LIBCPP_ASSERT(errno != 0, "Expected errno to be non-zero");
   return error_code(errno, generic_category());
 }
 


        


More information about the libcxx-commits mailing list