I thought it would be useful to others who are new to the GCC codebase
to have an example of how to hash keys based on string contents rather
than pointer addresses (the fact that some hash maps key based on
semi-reliable pointers (due to ggc_mark_stringpool) into the symtab
gives a false sense of security).


- Michael
From 3433efe4ac558de05410a9b185f4ff0a01e7e5df Mon Sep 17 00:00:00 2001
From: Michael Ploujnikov <michael.ploujni...@oracle.com>
Date: Fri, 11 Jan 2019 09:22:14 -0500
Subject: [PATCH] Document how to hash based on key string contents.

gcc:

2019-01-18  Michael Ploujnikov  <michael.ploujni...@oracle.com>

	* hash-map-tests.c (test_map_of_strings_to_int): Document how
	to hash based on key string contents.
---
 gcc/hash-map-tests.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git gcc/hash-map-tests.c gcc/hash-map-tests.c
index 98b5830497..61da8233c4 100644
--- gcc/hash-map-tests.c
+++ gcc/hash-map-tests.c
@@ -77,6 +77,26 @@ test_map_of_strings_to_int ()
   m.remove (eric);
   ASSERT_EQ (5, m.elements ());
   ASSERT_EQ (NULL, m.get (eric));
+
+  /* A plain char * key is hashed based on its value (address), rather
+     than the string it points to.  */
+  char *another_ant = static_cast <char *> (xcalloc (4, 1));
+  another_ant[0] = 'a';
+  another_ant[1] = 'n';
+  another_ant[2] = 't';
+  another_ant[3] = 0;
+  ASSERT_NE (ant, another_ant);
+  unsigned prev_size = m.elements ();
+  ASSERT_EQ (false, m.put (another_ant, 7));
+  ASSERT_EQ (prev_size + 1, m.elements ());
+
+  /* Need to use string_hash or nofree_string_hash key types to hash
+     based on the string contents.  */
+  hash_map <nofree_string_hash, int> string_map;
+  ASSERT_EQ (false, string_map.put (ant, 1));
+  ASSERT_EQ (1, string_map.elements ());
+  ASSERT_EQ (true, string_map.put (another_ant, 5));
+  ASSERT_EQ (1, string_map.elements ());
 }
 
 /* Run all of the selftests within this file.  */
-- 
2.19.1

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to