From 7149dfe819b16c0238fb67f55a47e9295c20ff1b Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 20 Mar 2024 13:24:33 -0600 Subject: Make bcache more type-safe The bcache uses memcpy to make copies of the data passed to it. In C++, this is only safe for trivially-copyable types. This patch changes bcache to require this property, and slightly changes the API to make it easier to use when copying a single object. It also makes the new 'insert' template methods return the correct type. --- gdb/bcache.h | 25 ++++++++++++++++++++++++- gdb/gdbtypes.c | 2 +- gdb/macrotab.c | 12 ++++++------ gdb/psymtab.c | 6 ++---- 4 files changed, 33 insertions(+), 12 deletions(-) diff --git a/gdb/bcache.h b/gdb/bcache.h index 17a0988..a77cd00 100644 --- a/gdb/bcache.h +++ b/gdb/bcache.h @@ -152,7 +152,26 @@ struct bcache were newly added to the cache, or to false if the bytes were found in the cache. */ - const void *insert (const void *addr, int length, bool *added = nullptr); + template>> + const T *insert (const T *addr, int length, bool *added = nullptr) + { + return (const T *) this->insert ((const void *) addr, length, added); + } + + /* Find a copy of OBJECT in this bcache. If BCACHE has never seen + those bytes before, add a copy of them to BCACHE. In either + case, return a pointer to BCACHE's copy of that string. Since + the cached value is meant to be read-only, return a const buffer. + If ADDED is not NULL, set *ADDED to true if the bytes were newly + added to the cache, or to false if the bytes were found in the + cache. */ + + template>> + const T *insert (const T &object, bool *added = nullptr) + { + return (const T *) this->insert ((const void *) &object, sizeof (object), + added); + } /* Print statistics on this bcache's memory usage and efficacity at eliminating duplication. TYPE should be a string describing the @@ -173,6 +192,10 @@ protected: private: + /* Implementation of the templated 'insert' methods. */ + + const void *insert (const void *addr, int length, bool *added); + /* All the bstrings are allocated here. */ struct obstack m_cache {}; diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c index 5b3c5ac..f39fe3d 100644 --- a/gdb/gdbtypes.c +++ b/gdb/gdbtypes.c @@ -4372,7 +4372,7 @@ check_types_worklist (std::vector *worklist, /* If the type pair has already been visited, we know it is ok. */ - cache->insert (&entry, sizeof (entry), &added); + cache->insert (entry, &added); if (!added) continue; diff --git a/gdb/macrotab.c b/gdb/macrotab.c index f2012da..3a7f792 100644 --- a/gdb/macrotab.c +++ b/gdb/macrotab.c @@ -109,8 +109,9 @@ macro_free (void *object, struct macro_table *t) /* If the macro table T has a bcache, then cache the LEN bytes at ADDR there, and return the cached copy. Otherwise, just xmalloc a copy of the bytes, and return a pointer to that. */ -static const void * -macro_bcache (struct macro_table *t, const void *addr, int len) +template +static const U * +macro_bcache (struct macro_table *t, const U *addr, int len) { if (t->bcache) return t->bcache->insert (addr, len); @@ -119,7 +120,7 @@ macro_bcache (struct macro_table *t, const void *addr, int len) void *copy = xmalloc (len); memcpy (copy, addr, len); - return copy; + return (const U *) copy; } } @@ -130,7 +131,7 @@ macro_bcache (struct macro_table *t, const void *addr, int len) static const char * macro_bcache_str (struct macro_table *t, const char *s) { - return (const char *) macro_bcache (t, s, strlen (s) + 1); + return macro_bcache (t, s, strlen (s) + 1); } @@ -571,8 +572,7 @@ new_macro_definition (struct macro_table *t, cached_argv[i] = macro_bcache_str (t, argv[i]); /* Now bcache the array of argument pointers itself. */ - d->argv = ((const char * const *) - macro_bcache (t, cached_argv, cached_argv_size)); + d->argv = macro_bcache (t, cached_argv, cached_argv_size); } /* We don't bcache the entire definition structure because it's got diff --git a/gdb/psymtab.c b/gdb/psymtab.c index 596d87e..7d6648c 100644 --- a/gdb/psymtab.c +++ b/gdb/psymtab.c @@ -1062,10 +1062,8 @@ partial_symtab::add_psymbol (const partial_symbol &psymbol, bool added; /* Stash the partial symbol away in the cache. */ - partial_symbol *psym - = ((struct partial_symbol *) - partial_symtabs->psymbol_cache.insert - (&psymbol, sizeof (struct partial_symbol), &added)); + const partial_symbol *psym = partial_symtabs->psymbol_cache.insert (psymbol, + &added); /* Do not duplicate global partial symbols. */ if (where == psymbol_placement::GLOBAL && !added) -- cgit v1.1