diff options
author | Patrick Palka <ppalka@redhat.com> | 2021-02-01 10:27:45 -0500 |
---|---|---|
committer | Patrick Palka <ppalka@redhat.com> | 2021-02-01 10:27:45 -0500 |
commit | 7e534fb7d8256a605b6bdc12451d209af1bed329 (patch) | |
tree | dc32c0f20785dbb63135302296dcaa6dcf8fe6f6 /gcc | |
parent | bab669f2fc643cb1673aecd177eec1c773e9e48e (diff) | |
download | gcc-7e534fb7d8256a605b6bdc12451d209af1bed329.zip gcc-7e534fb7d8256a605b6bdc12451d209af1bed329.tar.gz gcc-7e534fb7d8256a605b6bdc12451d209af1bed329.tar.bz2 |
c++: Fix ICE from verify_ctor_sanity [PR98295]
In this testcase we're crashing during constexpr evaluation of the
ARRAY_REF b[0] as part of evaluation of the lambda's by-copy capture of b
(which is encoded as a VEC_INIT_EXPR<b>). Since A's constexpr default
constructor is not yet defined, b's initialization is not actually
constant, but because A is an empty type, evaluation of b from
cxx_eval_array_ref is successful and yields an empty CONSTRUCTOR.
And since this CONSTRUCTOR is empty, we {}-initialize the desired array
element, and end up crashing from verify_ctor_sanity during evaluation
of this initializer because we updated new_ctx.ctor without updating
new_ctx.object: the former now has type A[3] and the latter is still the
target of a TARGET_EXPR for b[0][0] created from cxx_eval_vec_init
(and so has type A).
This patch fixes this by setting new_ctx.object appropriately at the
same time that we set new_ctx.ctor from cxx_eval_array_reference.
gcc/cp/ChangeLog:
PR c++/98295
* constexpr.c (cxx_eval_array_reference): Also set
new_ctx.object when setting new_ctx.ctor.
gcc/testsuite/ChangeLog:
PR c++/98295
* g++.dg/cpp0x/constexpr-98295.C: New test.
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/cp/constexpr.c | 1 | ||||
-rw-r--r-- | gcc/testsuite/g++.dg/cpp0x/constexpr-98295.C | 11 |
2 files changed, 12 insertions, 0 deletions
diff --git a/gcc/cp/constexpr.c b/gcc/cp/constexpr.c index baa97a0..1dbc2db 100644 --- a/gcc/cp/constexpr.c +++ b/gcc/cp/constexpr.c @@ -3760,6 +3760,7 @@ cxx_eval_array_reference (const constexpr_ctx *ctx, tree t, tree empty_ctor = build_constructor (init_list_type_node, NULL); val = digest_init (elem_type, empty_ctor, tf_warning_or_error); new_ctx = *ctx; + new_ctx.object = t; new_ctx.ctor = build_constructor (elem_type, NULL); ctx = &new_ctx; } diff --git a/gcc/testsuite/g++.dg/cpp0x/constexpr-98295.C b/gcc/testsuite/g++.dg/cpp0x/constexpr-98295.C new file mode 100644 index 0000000..930bd5a --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/constexpr-98295.C @@ -0,0 +1,11 @@ +// PR c++/98295 +// { dg-do compile { target c++11 } } + +struct A { constexpr A(); }; + +void f() { + A b[2][3]; + [b] { }; +} + +constexpr A::A() {} |