diff options
author | Jason Merrill <jason@redhat.com> | 2022-04-26 11:15:04 -0400 |
---|---|---|
committer | Jason Merrill <jason@redhat.com> | 2022-05-17 18:09:24 -0400 |
commit | 2b0c8377729a3c62a05897136666574ab939aaab (patch) | |
tree | 7e773340c84575e560cb9d78468a761c16866b08 /gcc/cp/decl.cc | |
parent | 2c05a2d1a8e4697ea95d65c5da601aeae327e7a7 (diff) | |
download | gcc-2b0c8377729a3c62a05897136666574ab939aaab.zip gcc-2b0c8377729a3c62a05897136666574ab939aaab.tar.gz gcc-2b0c8377729a3c62a05897136666574ab939aaab.tar.bz2 |
c++: constexpr ref to array of array [PR102307]
The problem here is that first check_initializer calls
build_aggr_init_full_exprs, which does overload resolution, but then in the
case of failed constexpr throws away the result and does it again in
build_functional_cast. But in the first overload resolution,
reshape_init_array_1 decided to reuse the inner CONSTRUCTORs because
tf_error is set, so we know we're committed. But the second pass gets
confused by the CONSTRUCTORs with non-init-list types.
Fixed by avoiding a second pass: instead, pass the call from build_aggr_init
to build_cplus_new, which will turn it into a TARGET_EXPR. I don't bother
to change the object argument because it will be replaced later in
simplify_aggr_init_expr.
PR c++/102307
gcc/cp/ChangeLog:
* decl.cc (check_initializer): Use build_cplus_new in case of
constexpr failure.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1z/constexpr-array2.C: New test.
Diffstat (limited to 'gcc/cp/decl.cc')
-rw-r--r-- | gcc/cp/decl.cc | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/gcc/cp/decl.cc b/gcc/cp/decl.cc index 5654bc75..381259c 100644 --- a/gcc/cp/decl.cc +++ b/gcc/cp/decl.cc @@ -7413,12 +7413,19 @@ check_initializer (tree decl, tree init, int flags, vec<tree, va_gc> **cleanups) /* Declared constexpr or constinit, but no suitable initializer; massage init appropriately so we can pass it into store_init_value for the error. */ - if (CLASS_TYPE_P (type) - && (!init || TREE_CODE (init) == TREE_LIST)) + tree new_init = NULL_TREE; + if (!processing_template_decl + && TREE_CODE (init_code) == CALL_EXPR) + new_init = build_cplus_new (type, init_code, tf_none); + else if (CLASS_TYPE_P (type) + && (!init || TREE_CODE (init) == TREE_LIST)) + new_init = build_functional_cast (input_location, type, + init, tf_none); + if (new_init) { - init = build_functional_cast (input_location, type, - init, tf_none); - if (TREE_CODE (init) == TARGET_EXPR) + init = new_init; + if (TREE_CODE (init) == TARGET_EXPR + && !(flags & LOOKUP_ONLYCONVERTING)) TARGET_EXPR_DIRECT_INIT_P (init) = true; } init_code = NULL_TREE; |