aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2024-12-04 10:54:41 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2024-12-04 10:54:41 +0100
commit205591919214cb5610e9c3b2394f05a3cfaa7f68 (patch)
treed5b247b153896e6b78b6fe7a9cf60b17a33c4fc5
parent27b444a41a6afab8020183c4c5d3361e21635031 (diff)
downloadgcc-205591919214cb5610e9c3b2394f05a3cfaa7f68.zip
gcc-205591919214cb5610e9c3b2394f05a3cfaa7f68.tar.gz
gcc-205591919214cb5610e9c3b2394f05a3cfaa7f68.tar.bz2
c++: Fix up erroneous template error recovery ICE [PR117826]
The testcase in the PR (which can't be easily reduced and is way too large and has way too many errors) results in an ICE, because the erroneous_templates hash_map holds trees of erroneous templates across ggc_collect and some of the templates in there could be removed, so the later lookup can crash on comparison of already freed and reused trees. The following patch makes the hash_map GTY((cache)) marked. The cp-tree.h changes before the erroneous_template declaration are needed to make gengtype happy, it didn't like using directive nor using a template-id as a template parameter. It is marked cache because if a decl would be solely referenced from the erroneous_templates hash_map, then nothing would look it up. 2024-12-04 Jakub Jelinek <jakub@redhat.com> PR c++/117826 * cp-tree.h (struct decl_location_traits): New type. (erroneous_templates_t): Change using into typedef. (erroneous_templates): Add GTY((cache)). * error.cc (cp_adjust_diagnostic_info): Use hash_map_safe_get_or_insert<true> rather than hash_map_safe_get_or_insert<false> for erroneous_templates.
-rw-r--r--gcc/cp/cp-tree.h7
-rw-r--r--gcc/cp/error.cc4
2 files changed, 6 insertions, 5 deletions
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 0d6fce0..29f28d5 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -7222,9 +7222,10 @@ extern location_t location_of (tree);
extern void qualified_name_lookup_error (tree, tree, tree,
location_t);
-using erroneous_templates_t
- = hash_map<tree, location_t, simple_hashmap_traits<tree_decl_hash, location_t>>;
-extern erroneous_templates_t *erroneous_templates;
+struct decl_location_traits
+ : simple_cache_map_traits<tree_decl_hash, location_t> { };
+typedef hash_map<tree, location_t, decl_location_traits> erroneous_templates_t;
+extern GTY((cache)) erroneous_templates_t *erroneous_templates;
extern bool cp_seen_error ();
#define seen_error() cp_seen_error ()
diff --git a/gcc/cp/error.cc b/gcc/cp/error.cc
index 10d7f46..ce8d5b1 100644
--- a/gcc/cp/error.cc
+++ b/gcc/cp/error.cc
@@ -237,8 +237,8 @@ cp_adjust_diagnostic_info (diagnostic_context *context,
bool existed;
location_t &error_loc
- = hash_map_safe_get_or_insert<false> (erroneous_templates,
- tmpl, &existed);
+ = hash_map_safe_get_or_insert<true> (erroneous_templates,
+ tmpl, &existed);
if (!existed)
/* Remember that this template had a parse-time error so
that we'll ensure a hard error has been issued upon