diff options
author | Marek Polacek <polacek@redhat.com> | 2024-05-08 15:43:58 -0400 |
---|---|---|
committer | Marek Polacek <polacek@redhat.com> | 2024-05-15 13:27:38 -0400 |
commit | 1a05332bbac98a4c002bef3fb45a3ad9d56b3a71 (patch) | |
tree | 3a5708dbe82bf60df2d728df829c2a2b4f0f40e5 | |
parent | 0b3eac4b54a52bf206b88743d1e987badc97cff4 (diff) | |
download | gcc-1a05332bbac98a4c002bef3fb45a3ad9d56b3a71.zip gcc-1a05332bbac98a4c002bef3fb45a3ad9d56b3a71.tar.gz gcc-1a05332bbac98a4c002bef3fb45a3ad9d56b3a71.tar.bz2 |
c++: ICE with reference NSDMI [PR114854]
Here we crash on a cp_gimplify_expr/TARGET_EXPR assert:
/* A TARGET_EXPR that expresses direct-initialization should have been
elided by cp_gimplify_init_expr. */
gcc_checking_assert (!TARGET_EXPR_DIRECT_INIT_P (*expr_p));
the TARGET_EXPR in question is created for the NSDMI in:
class Vector { int m_size; };
struct S {
const Vector &vec{};
};
where we first need to create a Vector{} temporary, and then bind the
vec reference to it. The temporary is represented by a TARGET_EXPR
and it cannot be elided. When we create an object of type S, we get
D.2848 = {.vec=(const struct Vector &) &TARGET_EXPR <D.2840, {.m_size=0}>}
where the TARGET_EXPR is no longer direct-initializing anything.
Fixed by not setting TARGET_EXPR_DIRECT_INIT_P in convert_like_internal/ck_user.
PR c++/114854
gcc/cp/ChangeLog:
* call.cc (convert_like_internal) <case ck_user>: Don't set
TARGET_EXPR_DIRECT_INIT_P.
gcc/testsuite/ChangeLog:
* g++.dg/cpp1y/nsdmi-aggr22.C: New test.
-rw-r--r-- | gcc/cp/call.cc | 6 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr22.C | 12 |
2 files changed, 13 insertions, 5 deletions
diff --git a/gcc/cp/call.cc b/gcc/cp/call.cc index e058da7..ed68eb3 100644 --- a/gcc/cp/call.cc +++ b/gcc/cp/call.cc @@ -8597,16 +8597,12 @@ convert_like_internal (conversion *convs, tree expr, tree fn, int argnum, && TYPE_HAS_DEFAULT_CONSTRUCTOR (totype) && !processing_template_decl) { - bool direct = CONSTRUCTOR_IS_DIRECT_INIT (expr); if (abstract_virtuals_error (NULL_TREE, totype, complain)) return error_mark_node; expr = build_value_init (totype, complain); expr = get_target_expr (expr, complain); if (expr != error_mark_node) - { - TARGET_EXPR_LIST_INIT_P (expr) = true; - TARGET_EXPR_DIRECT_INIT_P (expr) = direct; - } + TARGET_EXPR_LIST_INIT_P (expr) = true; return expr; } diff --git a/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr22.C b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr22.C new file mode 100644 index 0000000..a4f9ae1 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/nsdmi-aggr22.C @@ -0,0 +1,12 @@ +// PR c++/114854 +// { dg-do compile { target c++14 } } + +struct Vector { + int m_size; +}; +struct S { + const Vector &vec{}; +}; + +void spawn(S); +void test() { spawn({}); } |