summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathaniel Shead <nathanieloshead@gmail.com>2024-03-01 11:08:23 +1100
committerNathaniel Shead <nathanieloshead@gmail.com>2024-03-02 09:04:16 +1100
commit852b58552991099141f9df5782e1f28d8606af9d (patch)
tree9d323a1d3b8177202cbe7905232a07975365aea1
parent2823b4d96d9ec4ad4e67e5e8edaa1b060a467491 (diff)
c++: Stream definitions for implicit instantiations [PR114170]
An implicit instantiation has an initializer depending on whether DECL_INITIALIZED_P is set (like normal VAR_DECLs) which needs to be written to ensure that consumers of header modules properly emit definitions for these instantiations. This patch ensures that we correctly fallback to checking this flag when DECL_INITIAL is not set for a template instantiation. For variables with non-trivial dynamic initialization, DECL_INITIAL can be empty after 'split_nonconstant_init' but DECL_INITIALIZED_P is still set; we need to check the latter to determine if we need to go looking for a definition to emit (often in 'static_aggregates' here). This is the case in the linked testcase. However, for template specialisations (not instantiations?) we primarily care about DECL_INITIAL; if the variable has initialization depending on a template parameter then we'll need to emit that definition even though it doesn't yet have DECL_INITIALIZED_P set; this is the case in e.g. template <int N> int value = N; As a drive-by fix, also ensures that the count of initializers matches the actual number of initializers written. This doesn't seem to be necessary for correctness in the current testsuite, but feels wrong and makes debugging harder when initializers aren't properly written for other reasons. PR c++/114170 gcc/cp/ChangeLog: * module.cc (has_definition): Fall back to DECL_INITIALIZED_P when DECL_INITIAL is not set on a template. (module_state::write_inits): Only increment count when initializers are actually written. gcc/testsuite/ChangeLog: * g++.dg/modules/var-tpl-2_a.H: New test. * g++.dg/modules/var-tpl-2_b.C: New test. Signed-off-by: Nathaniel Shead <nathanieloshead@gmail.com>
-rw-r--r--gcc/cp/module.cc9
-rw-r--r--gcc/testsuite/g++.dg/modules/var-tpl-2_a.H10
-rw-r--r--gcc/testsuite/g++.dg/modules/var-tpl-2_b.C10
3 files changed, 26 insertions, 3 deletions
diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
index 1b2ba2e0fa8..355ee5d775d 100644
--- a/gcc/cp/module.cc
+++ b/gcc/cp/module.cc
@@ -11585,9 +11585,11 @@ has_definition (tree decl)
break;
case VAR_DECL:
+ /* DECL_INITIALIZED_P might not be set on a dependent VAR_DECL. */
if (DECL_LANG_SPECIFIC (decl)
- && DECL_TEMPLATE_INFO (decl))
- return DECL_INITIAL (decl);
+ && DECL_TEMPLATE_INFO (decl)
+ && DECL_INITIAL (decl))
+ return true;
else
{
if (!DECL_INITIALIZED_P (decl))
@@ -17528,13 +17530,14 @@ module_state::write_inits (elf_out *to, depset::hash &table, unsigned *crc_ptr)
tree list = static_aggregates;
for (int passes = 0; passes != 2; passes++)
{
- for (tree init = list; init; init = TREE_CHAIN (init), count++)
+ for (tree init = list; init; init = TREE_CHAIN (init))
if (TREE_LANG_FLAG_0 (init))
{
tree decl = TREE_VALUE (init);
dump ("Initializer:%u for %N", count, decl);
sec.tree_node (decl);
+ ++count;
}
list = tls_aggregates;
diff --git a/gcc/testsuite/g++.dg/modules/var-tpl-2_a.H b/gcc/testsuite/g++.dg/modules/var-tpl-2_a.H
new file mode 100644
index 00000000000..607fc0b808e
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/var-tpl-2_a.H
@@ -0,0 +1,10 @@
+// PR c++/114170
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+
+inline int f() { return 42; }
+
+template<class>
+inline int v = f();
+
+inline int g() { return v<int>; }
diff --git a/gcc/testsuite/g++.dg/modules/var-tpl-2_b.C b/gcc/testsuite/g++.dg/modules/var-tpl-2_b.C
new file mode 100644
index 00000000000..6d2ef4004e6
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/var-tpl-2_b.C
@@ -0,0 +1,10 @@
+// PR c++/114170
+// { dg-module-do run }
+// { dg-additional-options "-fmodules-ts" }
+
+import "var-tpl-2_a.H";
+
+int main() {
+ if (v<int> != 42)
+ __builtin_abort();
+}