https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92761

Martin Sebor <msebor at gcc dot gnu.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |build
             Status|RESOLVED                    |UNCONFIRMED
         Resolution|WONTFIX                     |---

--- Comment #5 from Martin Sebor <msebor at gcc dot gnu.org> ---
Andrew, please avoid closing reports of valid problems that you don't
understand.

As I explained in comment #0, the hash_table invokes the assignment operator
directly, without going through the traits class.  The hash traits classes also
don't provide an "assign" function, so defining such a class is not a solution.

A test case that includes a traits class is below.

struct S
{
  S (): p (&p) { }
  S (const S &s): p (&p) { gcc_assert (s.p == &s.p); }
  S& operator= (const S &s) {
    gcc_assert (p == &p);
    gcc_assert (s.p == &s.p);
    return *this; }
  ~S () { gcc_assert (p == &p); }
  void *p;
};

typedef int_hash<int, INT_MIN, 0> IntHash;

template <class T>
void destroy (T &x)
{
  x.~T ();
}

template <>
struct simple_hashmap_traits<IntHash, S>
{
  typedef IntHash            Traits;
  typedef Traits::value_type key_type;

  static hashval_t hash (key_type x) { return x; }
  static bool equal_keys (key_type x, key_type y) { return x == y; }

  template <typename T>
  static void remove (T &x)
  {
    Traits::remove (x.m_key);
    destroy (x.m_value);
  }

  template <typename T>
  static bool is_empty (const T &x)
  {
    return Traits::is_empty (x.m_key);
  }

  template <typename T> static bool is_deleted (const T &x)
  {
    return Traits::is_deleted (x.m_key);
  }

  template <typename T> static void mark_empty (T &x)
  {
    Traits::mark_empty (x.m_key);
  }

  template <typename T> static void mark_deleted (T &x)
  {
    Traits::mark_deleted (x.m_key);
  }
};

hash_map<int, S, simple_hashmap_traits<IntHash, S> > x;

static void test_hash_table ()
{
  for (int i = 1; i != 32; ++i)
    x.put (i, S ());

  x.empty ();
}

/* Parse one entire translation unit.  */

void
c_parse_file (void)
{
  test_hash_table ();
  ...
}

internal compiler error: in operator=, at cp/parser.c:43419
0xaeedd1 S::operator=(S const&)
        /src/gcc/61339/gcc/cp/parser.c:43419
0xaf3bb2 hash_map<int, S, simple_hashmap_traits<int_hash<int, -2147483648, 0>,
S> >::hash_entry::operator=(hash_map<int, S,
simple_hashmap_traits<int_hash<int, -2147483648, 0>, S> >::hash_entry const&)
        /src/gcc/61339/gcc/hash-map.h:42
0xaf3d58 hash_table<hash_map<int, S, simple_hashmap_traits<int_hash<int,
-2147483648, 0>, S> >::hash_entry, false, xcallocator>::expand()
        /src/gcc/61339/gcc/hash-table.h:822
0xaf2259 hash_table<hash_map<int, S, simple_hashmap_traits<int_hash<int,
-2147483648, 0>, S> >::hash_entry, false, xcallocator>::find_slot_with_hash(int
const&, unsigned int, insert_option)
        /src/gcc/61339/gcc/hash-table.h:971
0xaf03b1 hash_map<int, S, simple_hashmap_traits<int_hash<int, -2147483648, 0>,
S> >::put(int const&, S const&)
        /src/gcc/61339/gcc/hash-map.h:165
0xaea3b9 test_hash_table
        /src/gcc/61339/gcc/cp/parser.c:43477
0xaea3eb c_parse_file()
        /src/gcc/61339/gcc/cp/parser.c:43487
0xcd3645 c_common_parse_file()
        /src/gcc/61339/gcc/c-family/c-opts.c:1185
Please submit a full bug report,

Reply via email to