mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-10-10 12:55:00 +00:00
Improve diagnostics when an invalid hash is used in an unordered container.
This patch adds a static assertion that the specified hash meets the requirements of an enabled hash, and it ensures that the static assertion is evaluated before __compressed_pair is instantiated. That way the static assertion diagnostic is emitted first. llvm-svn: 296565
This commit is contained in:
parent
65f8cf945d
commit
acb21581d7
@ -871,11 +871,20 @@ public:
|
||||
template <class _Key, class _Hash, class _Equal, class _Alloc>
|
||||
struct __diagnose_hash_table_helper {
|
||||
static constexpr bool __trigger_diagnostics()
|
||||
_LIBCPP_DIAGNOSE_WARNING(!__invokable<_Hash const&, _Key const&>::value,
|
||||
"the specified hash functor does not provide a const call operator")
|
||||
_LIBCPP_DIAGNOSE_WARNING(!__invokable<_Equal const&, _Key const&, _Key const&>::value,
|
||||
"the specified comparator type does not provide a const call operator")
|
||||
{ return true; }
|
||||
_LIBCPP_DIAGNOSE_WARNING(__has_enabled_hash<_Key, _Hash>::value
|
||||
&& !__invokable<_Hash const&, _Key const&>::value,
|
||||
"the specified hash functor does not provide a const call operator")
|
||||
_LIBCPP_DIAGNOSE_WARNING(is_copy_constructible<_Equal>::value
|
||||
&& !__invokable<_Equal const&, _Key const&, _Key const&>::value,
|
||||
"the specified comparator type does not provide a const call operator")
|
||||
{
|
||||
static_assert(__has_enabled_hash<_Key, _Hash>::value,
|
||||
"the specified hash functor does not meet the requirements for an "
|
||||
"enabled hash");
|
||||
static_assert(is_copy_constructible<_Equal>::value,
|
||||
"the specified comparator is required to be copy constructible");
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
template <class _Key, class _Value, class _Hash, class _Equal, class _Alloc>
|
||||
@ -951,6 +960,10 @@ private:
|
||||
typedef allocator_traits<__pointer_allocator> __pointer_alloc_traits;
|
||||
typedef typename __bucket_list_deleter::pointer __node_pointer_pointer;
|
||||
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
static_assert(__diagnose_hash_table_helper<_Tp, _Hash, _Equal, _Alloc>::__trigger_diagnostics(), "");
|
||||
#endif
|
||||
|
||||
// --- Member data begin ---
|
||||
__bucket_list __bucket_list_;
|
||||
__compressed_pair<__first_node, __node_allocator> __p1_;
|
||||
@ -1482,13 +1495,13 @@ __hash_table<_Tp, _Hash, _Equal, _Alloc>::__hash_table(__hash_table&& __u,
|
||||
template <class _Tp, class _Hash, class _Equal, class _Alloc>
|
||||
__hash_table<_Tp, _Hash, _Equal, _Alloc>::~__hash_table()
|
||||
{
|
||||
#if defined(_LIBCPP_CXX03_LANG)
|
||||
static_assert((is_copy_constructible<key_equal>::value),
|
||||
"Predicate must be copy-constructible.");
|
||||
static_assert((is_copy_constructible<hasher>::value),
|
||||
"Hasher must be copy-constructible.");
|
||||
#ifndef _LIBCPP_CXX03_LANG
|
||||
static_assert(__diagnose_hash_table_helper<_Tp, _Hash, _Equal, _Alloc>::__trigger_diagnostics(), "");
|
||||
#endif
|
||||
|
||||
__deallocate_node(__p1_.first().__next_);
|
||||
#if _LIBCPP_DEBUG_LEVEL >= 2
|
||||
__get_db()->__erase_c(this);
|
||||
|
@ -0,0 +1,32 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is dual licensed under the MIT and the University of Illinois Open
|
||||
// Source Licenses. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// UNSUPPORTED: c++98, c++03
|
||||
// REQUIRES: diagnose-if-support
|
||||
|
||||
// <unordered_set>
|
||||
|
||||
// Test that we generate a reasonable diagnostic when the specified hash is
|
||||
// not enabled.
|
||||
|
||||
#include <unordered_set>
|
||||
#include <utility>
|
||||
|
||||
using VT = std::pair<int, int>;
|
||||
using Set = std::unordered_set<VT>;
|
||||
|
||||
int main() {
|
||||
|
||||
Set s; // expected-error@__hash_table:* {{the specified hash functor does not meet the requirements for an enabled hash}}
|
||||
|
||||
// FIXME: It would be great to suppress the below diagnostic all together.
|
||||
// but for now it's sufficient that it appears last. However there is
|
||||
// currently no way to test the order diagnostics are issued.
|
||||
// expected-error@memory:* {{call to implicitly-deleted default constructor of 'std::__1::hash<std::__1::pair<int, int> >'}}
|
||||
}
|
Loading…
Reference in New Issue
Block a user