[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