diff --git a/gcc/cp/semantics.cc b/gcc/cp/semantics.cc index a43ff6e2ab2..329c524a509 100644 --- a/gcc/cp/semantics.cc +++ b/gcc/cp/semantics.cc @@ -5029,9 +5029,13 @@ expand_or_defer_fn_1 (tree fn) /* We don't want to process FN again, so pretend we've written it out, even though we haven't. */ TREE_ASM_WRITTEN (fn) = 1; - /* If this is a constexpr function, keep DECL_SAVED_TREE. */ + /* If this is a constexpr function we still need the body to be + able to evaluate it. Similarly, with modules we only stream + the maybe-in-charge cdtor and regenerate the clones from it on + demand, so we also need to keep the body. Otherwise we don't + need it anymore. */ if (!DECL_DECLARED_CONSTEXPR_P (fn) - && !(modules_p () && DECL_DECLARED_INLINE_P (fn))) + && !(modules_p () && vague_linkage_p (fn))) DECL_SAVED_TREE (fn) = NULL_TREE; return false; } diff --git a/gcc/testsuite/g++.dg/modules/pr104040_a.C b/gcc/testsuite/g++.dg/modules/pr104040_a.C new file mode 100644 index 00000000000..ea36ce0a798 --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr104040_a.C @@ -0,0 +1,14 @@ +// PR c++/104040 +// { dg-additional-options "-fmodules-ts" } +// { dg-module-cmi test } + +export module test; + +export template +struct test { + ~test() {} +}; + +test use() { + return {}; +} diff --git a/gcc/testsuite/g++.dg/modules/pr104040_b.C b/gcc/testsuite/g++.dg/modules/pr104040_b.C new file mode 100644 index 00000000000..efe014673fb --- /dev/null +++ b/gcc/testsuite/g++.dg/modules/pr104040_b.C @@ -0,0 +1,8 @@ +// PR c++/104040 +// { dg-additional-options "-fmodules-ts" } + +import test; + +int main() { + test t{}; +}