aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@acm.org>2021-03-05 10:34:23 -0800
committerNathan Sidwell <nathan@acm.org>2021-03-05 11:54:57 -0800
commit1e5cdb9f896fb220b26fd2080406504c4badf5af (patch)
tree535defa79bc6ca9de6a50d1f024e30ef44b417cd /gcc
parent3d9577c254003f2d18185015b75ce6e3e4af9ca2 (diff)
downloadgcc-1e5cdb9f896fb220b26fd2080406504c4badf5af.zip
gcc-1e5cdb9f896fb220b26fd2080406504c4badf5af.tar.gz
gcc-1e5cdb9f896fb220b26fd2080406504c4badf5af.tar.bz2
c++: Local instantiations of imported specializations [PR 99377]
This turned out to be the function version of the previous fix. We can import an implicit specialization declaration that we need to instantiate. We must mark the instantiation so we remember to stream it. PR c++/99377 gcc/cp/ * pt.c (instantiate_decl): Call set_instantiating_module. gcc/testsuite/ * g++.dg/modules/pr99377_a.H: New. * g++.dg/modules/pr99377_b.C: New. * g++.dg/modules/pr99377_c.C: New.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/pt.c1
-rw-r--r--gcc/testsuite/g++.dg/modules/pr99377_a.H21
-rw-r--r--gcc/testsuite/g++.dg/modules/pr99377_b.C10
-rw-r--r--gcc/testsuite/g++.dg/modules/pr99377_c.C8
4 files changed, 40 insertions, 0 deletions
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 8ca3dc8..1f3cd9c 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -26154,6 +26154,7 @@ instantiate_decl (tree d, bool defer_ok, bool expl_inst_class_mem_p)
}
else
{
+ set_instantiating_module (d);
if (variable_template_p (gen_tmpl))
note_variable_template_instantiation (d);
instantiate_body (td, args, d, false);
diff --git a/gcc/testsuite/g++.dg/modules/pr99377_a.H b/gcc/testsuite/g++.dg/modules/pr99377_a.H
new file mode 100644
index 0000000..b5e5a3f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr99377_a.H
@@ -0,0 +1,21 @@
+// PR 99377 failed to stream locally instantiated member
+// link failure in function `Check(Widget<int> const&)':
+// bug_c.ii:(.text._Z5CheckRK6WidgetIiE[_Z5CheckRK6WidgetIiE]+0x14): undefined reference to `Widget<int>::Second() const'
+// { dg-module-do link }
+// { dg-additional-options -fmodule-header }
+// { dg-module-cmi {} }
+template<typename>
+struct Widget
+{
+ Widget (int) { }
+
+ bool First() const { return true; }
+
+ bool Second () const { return true;}
+};
+
+inline void Frob (const Widget<int>& w) noexcept
+{
+ w.First ();
+}
+
diff --git a/gcc/testsuite/g++.dg/modules/pr99377_b.C b/gcc/testsuite/g++.dg/modules/pr99377_b.C
new file mode 100644
index 0000000..7782637
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr99377_b.C
@@ -0,0 +1,10 @@
+// { dg-additional-options -fmodules-ts }
+export module Foo;
+// { dg-module-cmi Foo }
+import "pr99377_a.H";
+
+export inline bool Check (const Widget<int>& w)
+{
+ return w.Second ();
+}
+
diff --git a/gcc/testsuite/g++.dg/modules/pr99377_c.C b/gcc/testsuite/g++.dg/modules/pr99377_c.C
new file mode 100644
index 0000000..287388f
--- /dev/null
+++ b/gcc/testsuite/g++.dg/modules/pr99377_c.C
@@ -0,0 +1,8 @@
+// { dg-additional-options -fmodules-ts }
+
+import Foo;
+
+int main ()
+{
+ return Check (0) ? 0 : 1;
+}