aboutsummaryrefslogtreecommitdiff
path: root/gcc/cp/pt.cc
diff options
context:
space:
mode:
authorNathaniel Shead <nathanieloshead@gmail.com>2024-08-16 15:06:33 +1000
committerNathaniel Shead <nathanieloshead@gmail.com>2024-08-20 17:14:04 +1000
commit0b7904e274fbd6a736d63c0fed28ea32f9cb5997 (patch)
tree2e7edaa335de181e376c44d211f0673be1cfc977 /gcc/cp/pt.cc
parentc310d29cac1c3a770f48ab8bb2d295ef9cc08c53 (diff)
downloadgcc-0b7904e274fbd6a736d63c0fed28ea32f9cb5997.zip
gcc-0b7904e274fbd6a736d63c0fed28ea32f9cb5997.tar.gz
gcc-0b7904e274fbd6a736d63c0fed28ea32f9cb5997.tar.bz2
c++/modules: Avoid rechecking initializers when streaming NTTPs [PR116382]
When reading an NTTP we call get_template_parm_object which delegates setting of DECL_INITIAL to the general cp_finish_decl procedure, which calls check_initializer to validate and record it. Apart from being unnecessary (it must have already been validated by the writing module), this also causes errors in cases like the linked PR, as validating may end up needing to call lazy_load_pendings to determine any specialisations that may exist which violates assumptions of the modules streaming code. This patch works around the issue by adding a flag to get_template_parm_object to disable these checks when not needed. PR c++/116382 gcc/cp/ChangeLog: * cp-tree.h (get_template_parm_object): Add check_init param. * module.cc (trees_in::tree_node): Pass check_init=false when building NTTPs. * pt.cc (get_template_parm_object): Prevent cp_finish_decl from validating the initializer when check_init=false. gcc/testsuite/ChangeLog: * g++.dg/modules/tpl-nttp-1_a.C: New test. * g++.dg/modules/tpl-nttp-1_b.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com> Reviewed-by: Jason Merrill <jason@redhat.com>
Diffstat (limited to 'gcc/cp/pt.cc')
-rw-r--r--gcc/cp/pt.cc18
1 files changed, 14 insertions, 4 deletions
diff --git a/gcc/cp/pt.cc b/gcc/cp/pt.cc
index 32d164f..76edc7a 100644
--- a/gcc/cp/pt.cc
+++ b/gcc/cp/pt.cc
@@ -7361,10 +7361,11 @@ create_template_parm_object (tree expr, tsubst_flags_t complain)
static GTY(()) hash_map<tree, tree> *tparm_obj_values;
/* Find or build an nttp object for (already-validated) EXPR with name
- NAME. */
+ NAME. When CHECK_INIT is false we don't need to process the initialiser,
+ it's already been done. */
tree
-get_template_parm_object (tree expr, tree name)
+get_template_parm_object (tree expr, tree name, bool check_init/*=true*/)
{
tree decl = get_global_binding (name);
if (decl)
@@ -7385,11 +7386,20 @@ get_template_parm_object (tree expr, tree name)
{
/* If EXPR contains any PTRMEM_CST, they will get clobbered by
lower_var_init before we're done mangling. So store the original
- value elsewhere. */
- tree copy = unshare_constructor (expr);
+ value elsewhere. We only need to unshare EXPR if it's not yet
+ been processed. */
+ tree copy = check_init ? unshare_constructor (expr) : expr;
hash_map_safe_put<hm_ggc> (tparm_obj_values, decl, copy);
}
+ if (!check_init)
+ {
+ /* The EXPR is the already processed initializer, set it on the NTTP
+ object now so that cp_finish_decl doesn't do it again later. */
+ DECL_INITIAL (decl) = expr;
+ DECL_INITIALIZED_P (decl) = 1;
+ }
+
pushdecl_top_level_and_finish (decl, expr);
return decl;