Modify some library internals to work without <stdint.h>
authorJonathan Wakely <jwakely@redhat.com>
Thu, 26 Jul 2018 14:02:05 +0000 (15:02 +0100)
committerJonathan Wakely <redi@gcc.gnu.org>
Thu, 26 Jul 2018 14:02:05 +0000 (15:02 +0100)
std::__detail::__clp2 used uint_fast32_t and uint_fast64_t without
checking _GLIBCXX_USE_C99_STDINT_TR1 which was a potential bug. A
simpler implementation based on the new std::__ceil2 code performs
better and doesn't depend on <stdint.h> types.

std::align and other C++11 functions in <memory> where unnecessarily
missing when _GLIBCXX_USE_C99_STDINT_TR1 was not defined.

* include/bits/hashtable_policy.h (__detail::__clp2): Use faster
implementation that doesn't depend on <stdint.h> types.
* include/std/memory (align) [!_GLIBCXX_USE_C99_STDINT_TR1]: Use
std::size_t when std::uintptr_t is not usable.
[!_GLIBCXX_USE_C99_STDINT_TR1] (pointer_safety, declare_reachable)
(undeclare_reachable, declare_no_pointers, undeclare_no_pointers):
Define independent of _GLIBCXX_USE_C99_STDINT_TR1.

From-SVN: r263003

libstdc++-v3/ChangeLog
libstdc++-v3/include/bits/hashtable_policy.h
libstdc++-v3/include/std/memory

index 10b1496af8148cfef2e3cbb20aa78752f7aeb79b..66ee23d1fc78352f1a942d1935cac0c4ab9b57b3 100644 (file)
@@ -1,5 +1,13 @@
 2018-07-26  Jonathan Wakely  <jwakely@redhat.com>
 
+       * include/bits/hashtable_policy.h (__detail::__clp2): Use faster
+       implementation that doesn't depend on <stdint.h> types.
+       * include/std/memory (align) [!_GLIBCXX_USE_C99_STDINT_TR1]: Use
+       std::size_t when std::uintptr_t is not usable.
+       [!_GLIBCXX_USE_C99_STDINT_TR1] (pointer_safety, declare_reachable)
+       (undeclare_reachable, declare_no_pointers, undeclare_no_pointers):
+       Define independent of _GLIBCXX_USE_C99_STDINT_TR1.
+
        * include/bits/basic_string.h [!_GLIBCXX_USE_C99_STDINT_TR1]
        (hash<u16string>, hash<u32string>): Remove dependency on
        _GLIBCXX_USE_C99_STDINT_TR1.
index 3ff6b14a90f9ac4a6cc0a538450471accb5e9c73..d7497711071bc02278dcb4fcbfbe79f7968bfb38 100644 (file)
@@ -32,7 +32,7 @@
 #define _HASHTABLE_POLICY_H 1
 
 #include <tuple>               // for std::tuple, std::forward_as_tuple
-#include <cstdint>             // for std::uint_fast64_t
+#include <limits>              // for std::numeric_limits
 #include <bits/stl_algobase.h> // for std::min.
 
 namespace std _GLIBCXX_VISIBILITY(default)
@@ -504,27 +504,15 @@ namespace __detail
     { return __num & (__den - 1); }
   };
 
-  /// Compute closest power of 2.
-  _GLIBCXX14_CONSTEXPR
+  /// Compute closest power of 2 not less than __n
   inline std::size_t
   __clp2(std::size_t __n) noexcept
   {
-#if __SIZEOF_SIZE_T__ >= 8
-    std::uint_fast64_t __x = __n;
-#else
-    std::uint_fast32_t __x = __n;
-#endif
-    // Algorithm from Hacker's Delight, Figure 3-3.
-    __x = __x - 1;
-    __x = __x | (__x >> 1);
-    __x = __x | (__x >> 2);
-    __x = __x | (__x >> 4);
-    __x = __x | (__x >> 8);
-    __x = __x | (__x >>16);
-#if __SIZEOF_SIZE_T__ >= 8
-    __x = __x | (__x >>32);
-#endif
-    return __x + 1;
+    // Equivalent to return __n ? std::ceil2(__n) : 0;
+    if (__n < 2)
+      return __n;
+    return 1ul << (numeric_limits<unsigned long>::digits
+                   - __builtin_clzl(__n - 1ul));
   }
 
   /// Rehash policy providing power of 2 bucket numbers. Avoids modulo
index f3559a913272603c929786341dd31f5708b9500d..9689540fb817cc6b9c35cb3c1180522cf97d50d9 100644 (file)
@@ -88,8 +88,7 @@
 #endif
 
 #if __cplusplus >= 201103L
-#  include <cstdint>
-#  ifdef _GLIBCXX_USE_C99_STDINT_TR1
+#include <cstdint>
 namespace std _GLIBCXX_VISIBILITY(default)
 {
 _GLIBCXX_BEGIN_NAMESPACE_VERSION
@@ -113,7 +112,14 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 inline void*
 align(size_t __align, size_t __size, void*& __ptr, size_t& __space) noexcept
 {
+#ifdef _GLIBCXX_USE_C99_STDINT_TR1
   const auto __intptr = reinterpret_cast<uintptr_t>(__ptr);
+#else
+  // Cannot use std::uintptr_t so assume that std::size_t can be used instead.
+  static_assert(sizeof(size_t) >= sizeof(void*),
+      "std::size_t must be a suitable substitute for std::uintptr_t");
+  const auto __intptr = reinterpret_cast<unsigned long long>(__ptr);
+#endif
   const auto __aligned = (__intptr - 1u + __align) & -__align;
   const auto __diff = __aligned - __intptr;
   if ((__size + __diff) > __space)
@@ -147,7 +153,6 @@ get_pointer_safety() noexcept { return pointer_safety::relaxed; }
 
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
-#endif // _GLIBCXX_USE_C99_STDINT_TR1
 #endif // C++11
 
 #endif /* _GLIBCXX_MEMORY */