extern tree alias_template_specialization_p (const_tree, bool);
extern tree dependent_alias_template_spec_p (const_tree, bool);
extern bool dependent_opaque_alias_p (const_tree);
-extern tree get_template_parm_object (tree expr, tree mangle);
+extern tree get_template_parm_object (tree expr, tree mangle,
+ bool check_init = true);
extern tree tparm_object_argument (tree);
extern bool explicit_class_specialization_p (tree);
extern bool push_tinst_level (tree);
tree name = tree_node ();
if (!get_overrun ())
{
- res = get_template_parm_object (init, name);
+ /* We don't want to check the initializer as that may require
+ name lookup, which could recursively start lazy loading.
+ Instead we know that INIT is already valid so we can just
+ apply that directly. */
+ res = get_template_parm_object (init, name, /*check_init=*/false);
int tag = insert (res);
dump (dumper::TREE)
&& dump ("Created nttp object:%d %N", tag, name);
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)
{
/* 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;
--- /dev/null
+// PR c++/116382
+// { dg-additional-options "-fmodules-ts -std=c++20" }
+// { dg-module-cmi m:a }
+
+module m:a;
+template <typename> struct X {};
+template <X<int> nttp> struct index {};
+template struct index<{}>;
--- /dev/null
+// PR c++/116382
+// { dg-additional-options "-fmodules-ts -std=c++20" }
+// { dg-module-cmi m }
+
+export module m;
+import :a;