diff --git a/gcc/cp/cp-gimplify.cc b/gcc/cp/cp-gimplify.cc
index 4ec3de13008c00ed0da01df555a006766b28910f..45f4e27b8b742b3f674baf1025d383ea95cbceb4 100644
--- a/gcc/cp/cp-gimplify.cc
+++ b/gcc/cp/cp-gimplify.cc
@@ -1182,6 +1182,28 @@ taking_address_of_imm_fn_error (tree expr, tree decl)
   maybe_explain_promoted_consteval (loc, decl);
 }
 
+/* Build up an INIT_EXPR to initialize the object of a constructor call that
+   has been folded to a constant value.  CALL is the CALL_EXPR for the
+   constructor call; INIT is the value.  */
+
+static tree
+cp_build_init_expr_for_ctor (tree call, tree init)
+{
+  tree a = CALL_EXPR_ARG (call, 0);
+  if (is_dummy_object (a))
+    return init;
+  const bool return_this = targetm.cxx.cdtor_returns_this ();
+  const location_t loc = EXPR_LOCATION (call);
+  if (return_this)
+    a = cp_save_expr (a);
+  tree s = build_fold_indirect_ref_loc (loc, a);
+  init = cp_build_init_expr (s, init);
+  if (return_this)
+    init = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (call), init,
+		    fold_convert_loc (loc, TREE_TYPE (call), a));
+  return init;
+}
+
 /* A subroutine of cp_fold_r to handle immediate functions.  */
 
 static tree
@@ -1297,7 +1319,12 @@ cp_fold_immediate_r (tree *stmt_p, int *walk_subtrees, void *data_)
 	}
       /* We've evaluated the consteval function call.  */
       if (call_p)
-	*stmt_p = e;
+	{
+	  if (code == CALL_EXPR && DECL_CONSTRUCTOR_P (decl))
+	    *stmt_p = cp_build_init_expr_for_ctor (stmt, e);
+	  else
+	    *stmt_p = e;
+	}
     }
   /* We've encountered a function call that may turn out to be consteval
      later.  Store its caller so that we can ensure that the call is
@@ -3422,18 +3449,7 @@ cp_fold (tree x, fold_flags_t flags)
         if (TREE_CODE (r) != CALL_EXPR)
 	  {
 	    if (DECL_CONSTRUCTOR_P (callee))
-	      {
-		loc = EXPR_LOCATION (x);
-		tree a = CALL_EXPR_ARG (x, 0);
-		bool return_this = targetm.cxx.cdtor_returns_this ();
-		if (return_this)
-		  a = cp_save_expr (a);
-		tree s = build_fold_indirect_ref_loc (loc, a);
-		r = cp_build_init_expr (s, r);
-		if (return_this)
-		  r = build2_loc (loc, COMPOUND_EXPR, TREE_TYPE (x), r,
-				  fold_convert_loc (loc, TREE_TYPE (x), a));
-	      }
+	      r = cp_build_init_expr_for_ctor (x, r);
 	    x = r;
 	    break;
 	  }
diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval39.C b/gcc/testsuite/g++.dg/cpp2a/consteval39.C
new file mode 100644
index 0000000000000000000000000000000000000000..523e8260eab295149c8a9341517cefed511a4e54
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/consteval39.C
@@ -0,0 +1,27 @@
+// PR c++/117501
+// { dg-do run { target c++20 } }
+
+constexpr unsigned
+length ()
+{
+  bool __trans_tmp_1 = __builtin_is_constant_evaluated();
+  if (__trans_tmp_1)
+    return 42;
+  return 1;
+}
+struct basic_string_view {
+  constexpr basic_string_view(const char *) : _M_len{length()}, _M_str{} {}
+  long _M_len;
+  char _M_str;
+};
+struct QQQ {
+  consteval QQQ(basic_string_view d) : data(d) {}
+  basic_string_view data;
+};
+int
+main ()
+{
+  QQQ q("");
+  if (q.data._M_len != 42)
+    __builtin_abort ();
+}
diff --git a/gcc/testsuite/g++.dg/cpp2a/consteval40.C b/gcc/testsuite/g++.dg/cpp2a/consteval40.C
new file mode 100644
index 0000000000000000000000000000000000000000..4d3ba20092b1e0a49c57c7df74152ab00d56cc72
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/consteval40.C
@@ -0,0 +1,25 @@
+// PR c++/117501
+// { dg-do run { target c++20 } }
+
+constexpr int
+twiddle (int i)
+{
+ if (__builtin_is_constant_evaluated ())
+    return 3;
+  return i;
+}
+struct S {
+  constexpr S(int i) : i{twiddle (i)} {}
+  int i;
+};
+struct Q {
+  consteval Q(S s_) : s{s_, s_} {}
+  S s[2];
+};
+int
+main ()
+{
+  Q q(twiddle (42));
+  if (q.s[0].i != 3 || q.s[1].i != 3)
+    __builtin_abort ();
+}