[PATCH] c++/modules: PTRMEM_CST member considered unused [PR124981]
Jason Merrill
jason@redhat.com
Thu Apr 23 13:54:48 GMT 2026
On 4/22/26 4:19 PM, Patrick Palka wrote:
> Tested on x86_64-pc-linux-gnu, does this look OK for 17/16.2?
OK.
> -- >8 --
>
> Here from the importer side the specialization A<B, &B::g> has already
> been instantiated in module M, so we stream it in rather than
> instantiate it. We then proceed to instantiate A<B, &B::g>::f() whose
> definition invokes the pointer-to-member &B::g, clearly a use, but it
> turns out that nothing has marked B::g as used in _b.C and we complain
> at link time about an undefined reference.
>
> Without modules we would have marked B::g as used during instantiation
> of A<B, &B::g> via mark_template_arguments_used. But this instantiaton
> happens in module M, not the importer.
>
> This patch fixes this by force setting TREE_USED on PTRMEM_CST_MEMBER
> during stream-in, via the RTU macro, which seems sufficient to ensure
> B::g gets emitted. I don't fully understand the reason for this RTU macro
> but it's already used for streaming in operands of tcc_expression nodes
> and BASELINK_FUNCTIONS so using it for PTRMEM_CST_MEMBER doesn't seem too
> out of place.
>
> PR c++/124981
>
> gcc/cp/ChangeLog:
>
> * module.cc (trees_in::core_vals) <case PTRMEM_CST>: Use RTU
> instead of RT to stream PTRMEM_CST_MEMBER.
>
> gcc/testsuite/ChangeLog:
>
> * g++.dg/modules/ptrmem-1_a.C: New test.
> * g++.dg/modules/ptrmem-1_b.C: New test.
> ---
> gcc/cp/module.cc | 2 +-
> gcc/testsuite/g++.dg/modules/ptrmem-1_a.C | 21 +++++++++++++++++++++
> gcc/testsuite/g++.dg/modules/ptrmem-1_b.C | 10 ++++++++++
> 3 files changed, 32 insertions(+), 1 deletion(-)
> create mode 100644 gcc/testsuite/g++.dg/modules/ptrmem-1_a.C
> create mode 100644 gcc/testsuite/g++.dg/modules/ptrmem-1_b.C
>
> diff --git a/gcc/cp/module.cc b/gcc/cp/module.cc
> index e5547f7d029f..61e9e70936bd 100644
> --- a/gcc/cp/module.cc
> +++ b/gcc/cp/module.cc
> @@ -7443,7 +7443,7 @@ trees_in::core_vals (tree t)
> break;
>
> case PTRMEM_CST:
> - RT (((lang_tree_node *)t)->ptrmem.member);
> + RTU (((lang_tree_node *)t)->ptrmem.member);
> break;
>
> case STATIC_ASSERT:
> diff --git a/gcc/testsuite/g++.dg/modules/ptrmem-1_a.C b/gcc/testsuite/g++.dg/modules/ptrmem-1_a.C
> new file mode 100644
> index 000000000000..ca16c39bea3b
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/modules/ptrmem-1_a.C
> @@ -0,0 +1,21 @@
> +// PR c++/124981
> +// { dg-additional-options "-fmodules" }
> +// { dg-module-cmi M }
> +
> +export module M;
> +
> +template<class T, void (T::*F)() const>
> +struct A {
> + void f(const T& t) {
> + (t.*F)();
> + }
> +};
> +
> +export
> +template<class T>
> +struct B {
> + void g() const { }
> + A<B, &B::g> m;
> +};
> +
> +B<void> b;
> diff --git a/gcc/testsuite/g++.dg/modules/ptrmem-1_b.C b/gcc/testsuite/g++.dg/modules/ptrmem-1_b.C
> new file mode 100644
> index 000000000000..5c65bfc1fb10
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/modules/ptrmem-1_b.C
> @@ -0,0 +1,10 @@
> +// PR c++/124981
> +// { dg-additional-options "-fmodules" }
> +// { dg-module-do link }
> +
> +import M;
> +
> +int main() {
> + B<void> b;
> + b.m.f(b);
> +}
More information about the Libstdc++
mailing list