diff --git a/gcc/cp/typeck.cc b/gcc/cp/typeck.cc
index 71d879abef12a2d6670cabcb56de0617021c6494..bfc0c560c106f13eafe9f30f278331242a40c58b 100644
--- a/gcc/cp/typeck.cc
+++ b/gcc/cp/typeck.cc
@@ -4193,24 +4193,27 @@ get_member_function_from_ptrfunc (tree *instance_ptrptr, tree function,
       if (!nonvirtual && is_dummy_object (instance_ptr))
 	nonvirtual = true;
 
-      /* Use save_expr even when instance_ptr doesn't have side-effects,
-	 unless it is a simple decl (save_expr won't do anything on
-	 constants), so that we don't ubsan instrument the expression
-	 multiple times.  See PR116449.  */
+      /* Use force_target_expr even when instance_ptr doesn't have
+	 side-effects, unless it is a simple decl or constant, so
+	 that we don't ubsan instrument the expression multiple times.
+	 Don't use save_expr, as save_expr can avoid building a SAVE_EXPR
+	 and building a SAVE_EXPR manually can be optimized away during
+	 cp_fold.  See PR116449 and PR117259.  */
       if (TREE_SIDE_EFFECTS (instance_ptr)
-	  || (!nonvirtual && !DECL_P (instance_ptr)))
-	{
-	  instance_save_expr = save_expr (instance_ptr);
-	  if (instance_save_expr == instance_ptr)
-	    instance_save_expr = NULL_TREE;
-	  else
-	    instance_ptr = instance_save_expr;
-	}
+	  || (!nonvirtual
+	      && !DECL_P (instance_ptr)
+	      && !TREE_CONSTANT (instance_ptr)))
+	instance_ptr = instance_save_expr
+	  = force_target_expr (TREE_TYPE (instance_ptr), instance_ptr,
+			       complain);
 
       /* See above comment.  */
       if (TREE_SIDE_EFFECTS (function)
-	  || (!nonvirtual && !DECL_P (function)))
-	function = save_expr (function);
+	  || (!nonvirtual
+	      && !DECL_P (function)
+	      && !TREE_CONSTANT (function)))
+	function
+	  = force_target_expr (TREE_TYPE (function), function, complain);
 
       /* Start by extracting all the information from the PMF itself.  */
       e3 = pfn_from_ptrmemfunc (function);
diff --git a/gcc/testsuite/g++.dg/ubsan/pr117259.C b/gcc/testsuite/g++.dg/ubsan/pr117259.C
new file mode 100644
index 0000000000000000000000000000000000000000..2b7ba56c2a3678b9887cdc75d7e3e01811d61619
--- /dev/null
+++ b/gcc/testsuite/g++.dg/ubsan/pr117259.C
@@ -0,0 +1,13 @@
+// PR c++/117259
+// { dg-do compile }
+// { dg-options "-Wuninitialized -fsanitize=undefined" }
+
+struct A { void foo () {} };
+struct B { void (A::*b) (); B (void (A::*x) ()) : b(x) {}; };
+const B c[1] = { &A::foo };
+
+void
+foo (A *x, int y)
+{
+  (x->*c[y].b) ();
+}