[gcc r16-9417] c++: vrp and pmf conversion [PR126310]

Jason Merrill via Gcc-cvs <[email protected]>
Newsgroups gmane.comp.gcc.cvs
Message-ID <[email protected]>
https://gcc.gnu.org/g:2e1c4ce1640aa26f391e7aaf842500d98b9bc483

commit r16-9417-g2e1c4ce1640aa26f391e7aaf842500d98b9bc483
Author: Jason Merrill <[email protected]>
Date:   Mon Jul 27 13:25:33 2026 -0400

    c++: vrp and pmf conversion [PR126310]
    
    Here when trying to convert to EncodeFnTy, aka void (sub::*)(int&&), we were
    instead converting to void (sub::*)(ValuePart&&), and the optimization added
    by r16-5887 got confused by the values in the array initializer having
    different RECORD_TYPEs (with different FIELD_DECLs) from the type of the
    array.
    
    So let's correct the conversion to actually end with the requested type.
    
            PR c++/126310
    
    gcc/cp/ChangeLog:
    
            * call.cc (standard_conversion): Don't build a mixed METHOD_TYPE if
            it isn't needed.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/opt/pmf2.C: New test.
    
    (cherry picked from commit 0e429acc24a2305c77da1229c456788e50edcae9)

Diff:
---
 gcc/cp/call.cc                  | 16 ++++++++++------
 gcc/testsuite/g++.dg/opt/pmf2.C | 37 +++++++++++++++++++++++++++++++++++++
 2 files changed, 47 insertions(+), 6 deletions(-)

diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc
index 97cb0d6f0124..769d9b304999 100644
--- a/gcc/cp/call.cc
+++ b/gcc/cp/call.cc
@@ -1546,12 +1546,16 @@ standard_conversion (tree to, tree from, tree expr, bool c_cast_p,
 
       if (!same_type_p (fbase, tbase))
 	{
-	  from = build_memfn_type (fstat,
-				   tbase,
-				   cp_type_quals (tbase),
-				   type_memfn_rqual (tofn));
-	  from = build_ptrmemfunc_type (build_pointer_type (from));
-	  conv = build_conv (ck_pmem, from, conv);
+	  tree first = to;
+	  if (!same_type_p (tstat, fstat))
+	    {
+	      first = build_memfn_type (fstat,
+					tbase,
+					cp_type_quals (tbase),
+					type_memfn_rqual (tofn));
+	      first = build_ptrmemfunc_type (build_pointer_type (first));
+	    }
+	  conv = build_conv (ck_pmem, first, conv);
 	  conv->base_p = true;
 	}
       if (fnptr_conv_p (tstat, fstat))
diff --git a/gcc/testsuite/g++.dg/opt/pmf2.C b/gcc/testsuite/g++.dg/opt/pmf2.C
new file mode 100644
index 000000000000..88c38a8ea2a4
--- /dev/null
+++ b/gcc/testsuite/g++.dg/opt/pmf2.C
@@ -0,0 +1,37 @@
+// PR c++/126310
+// { dg-do run { target c++11 } }
+// { dg-additional-options -O }
+
+typedef int ValuePart;
+struct base0  {
+  int t;
+};
+struct base1 {
+  void gg(ValuePart&&) {symbols = 1; }
+  int symbols;
+};
+struct sub : base0, base1 {};
+
+using EncodeFnTy = void (sub::*)(int&&);
+static const EncodeFnTy encode_fns[]
+{
+    &sub::gg,
+    &sub::gg
+};
+
+[[gnu::noinline,gnu::noclone]]
+void f(sub &m, bool i)
+{
+ (&m->*encode_fns[i])(0);
+}
+int main()
+{
+    sub a;
+    a.t = 0;
+    a.symbols = 0;
+    f(a, 0);
+    if (a.t != 0)
+      __builtin_abort ();
+    if (a.symbols != 1)
+      __builtin_abort ();
+}
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.