set_constraints (clone, copy_node (ci));
SET_DECL_ASSEMBLER_NAME (clone, NULL_TREE);
+ DECL_ABSTRACT_P (clone) = false;
/* There's no pending inline data for this function. */
DECL_PENDING_INLINE_INFO (clone) = NULL;
DECL_PENDING_INLINE_P (clone) = 0;
tree, unification_kind_t, int,
struct conversion **,
bool, bool);
+extern void setup_explicit_instantiation_definition_linkage (tree);
extern void mark_decl_instantiated (tree, int);
extern int more_specialized_fn (tree, tree, int);
extern tree type_targs_deducible_from (tree, tree);
if (maybe_dup && DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (maybe_dup))
DECL_INITIALIZED_BY_CONSTANT_EXPRESSION_P (decl) = true;
tentative_decl_linkage (decl);
+ if (DECL_EXPLICIT_INSTANTIATION (decl)
+ && !DECL_EXTERNAL (decl))
+ setup_explicit_instantiation_definition_linkage (decl);
if (DECL_IMPLICIT_INSTANTIATION (decl)
|| (DECL_EXPLICIT_INSTANTIATION (decl)
&& !DECL_EXTERNAL (decl))
cfun->language->returns_abnormally = pdata.returns_abnormally;
cfun->language->infinite_loop = pdata.infinite_loop;
+ /* Make sure we emit explicit instantiations.
+ FIXME do we want to do this in expand_or_defer_fn instead? */
+ if (DECL_EXPLICIT_INSTANTIATION (decl)
+ && !DECL_EXTERNAL (decl))
+ setup_explicit_instantiation_definition_linkage (decl);
+
if (abstract)
;
else if (DECL_MAYBE_IN_CHARGE_CDTOR_P (decl))
DECL_NOT_REALLY_EXTERN (clone) = 1;
}
+/* DECL is an explicit instantiation definition, ensure that it will
+ be written out here and that it won't clash with other instantiations
+ in other translation units. */
+
+void
+setup_explicit_instantiation_definition_linkage (tree decl)
+{
+ mark_definable (decl);
+ mark_needed (decl);
+ /* Always make artificials weak. */
+ if (DECL_ARTIFICIAL (decl) && flag_weak)
+ comdat_linkage (decl);
+ /* We also want to put explicit instantiations in linkonce sections. */
+ else if (TREE_PUBLIC (decl))
+ maybe_make_one_only (decl);
+}
+
/* Called if RESULT is explicitly instantiated, or is a member of an
explicitly instantiated class. */
}
else
{
- mark_definable (result);
- mark_needed (result);
set_instantiating_module (result);
- /* Always make artificials weak. */
- if (DECL_ARTIFICIAL (result) && flag_weak)
- comdat_linkage (result);
- /* For WIN32 we also want to put explicit instantiations in
- linkonce sections. */
- else if (TREE_PUBLIC (result))
- maybe_make_one_only (result);
+ setup_explicit_instantiation_definition_linkage (result);
if (TREE_CODE (result) == FUNCTION_DECL
&& DECL_TEMPLATE_INSTANTIATED (result))
/* If the function has already been instantiated, clear DECL_EXTERNAL,
--- /dev/null
+template <typename> struct S {
+ S() {}
+};
+template <typename> inline int x = 0;
+
+extern template struct S<char>;
+extern template int x<char>;
+
+template <typename> int* foo() {
+ static int x;
+ return &x;
+};
+extern template int* foo<char>();
--- /dev/null
+// PR c++/118961
+// { dg-additional-options "-fmodule-header" }
+// { dg-module-cmi {} }
+// Test explicit instantiations get emitted with LTO
+
+#include "lto-1.h"
+template struct S<char>;
+template int x<char>;
+template int* foo<char>();
--- /dev/null
+// PR c++/118961
+// { dg-require-effective-target lto }
+// { dg-additional-options "-fmodules -flto" }
+
+#include "lto-1.h"
+
+S<char> s;
+int y = x<char>;
+int* p = foo<char>();
--- /dev/null
+// PR c++/118961
+// { dg-module-do link }
+// { dg-require-effective-target lto }
+// { dg-additional-options "-fmodules -fno-module-lazy -flto" }
+
+#include "lto-1_a.H"
+
+int main() {}
--- /dev/null
+// PR c++/118961
+// { dg-additional-options "-fmodule-header -std=c++20" }
+// { dg-module-cmi {} }
+// Test we correctly emit the bodies of cloned constructors.
+
+template <typename>
+struct S {
+ S() requires true {}
+};
+
+inline S<int> foo() { return {}; }
--- /dev/null
+// PR c++/118961
+// { dg-module-do link }
+// { dg-require-effective-target lto }
+// { dg-additional-options "-fmodules -flto -std=c++20" }
+
+import "lto-2_a.H";
+int main() {
+ foo();
+}
--- /dev/null
+// PR c++/118961
+// { dg-additional-options "-fmodule-header -std=c++20" }
+// { dg-module-cmi {} }
+// We shouldn't ICE when linking against the standard library.
+
+#include <string>
--- /dev/null
+// PR c++/118961
+// { dg-module-do link }
+// { dg-require-effective-target lto }
+// { dg-additional-options "-fmodules -flto -static -std=c++20" }
+
+import "lto-3_a.H";
+
+int main() {
+ std::string m_message;
+}