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));
+ suppress_warning (init);
+ }
+ return init;
+}
+
/* A subroutine of cp_fold_r to handle immediate functions. */
static tree
}
/* 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
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));
- suppress_warning (r);
- }
- }
+ r = cp_build_init_expr_for_ctor (x, r);
x = r;
break;
}
--- /dev/null
+// 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 ();
+}