Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk/branches? -- >8 -- This crash started with my r12-7803 but I believe the problem lies elsewhere.
build_vec_init has cleanup_flags whose purpose is -- if I grok this correctly -- to avoid destructing an object multiple times. Let's say we are initializing an array of A. Then we might end up in a scenario similar to initlist-eh1.C: try { call A::A in a loop // #0 try { call a fn using the array } finally { // #1 call A::~A in a loop } } catch { // #2 call A::~A in a loop } cleanup_flags makes us emit a statement like D.3048 = 2; at #0 to disable performing the cleanup at #2, since #1 will take care of the destruction of the array. But if we are not emitting the loop because we can use a constant initializer (and use a single { a, b, ...}), we shouldn't generate the statement resetting the iterator to its initial value. Otherwise we crash in gimplify_var_or_parm_decl because it gets the stray decl D.3048. PR c++/117985 gcc/cp/ChangeLog: * init.cc (build_vec_init): Clear CLEANUP_FLAGS if we're not generating the loop. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/initlist-array23.C: New test. * g++.dg/cpp0x/initlist-array24.C: New test. --- gcc/cp/init.cc | 4 +++ gcc/testsuite/g++.dg/cpp0x/initlist-array23.C | 28 +++++++++++++++++++ gcc/testsuite/g++.dg/cpp0x/initlist-array24.C | 27 ++++++++++++++++++ 3 files changed, 59 insertions(+) create mode 100644 gcc/testsuite/g++.dg/cpp0x/initlist-array23.C create mode 100644 gcc/testsuite/g++.dg/cpp0x/initlist-array24.C diff --git a/gcc/cp/init.cc b/gcc/cp/init.cc index ae516407c92..5dcb24ef735 100644 --- a/gcc/cp/init.cc +++ b/gcc/cp/init.cc @@ -5109,6 +5109,10 @@ build_vec_init (tree base, tree maxindex, tree init, { if (!saw_non_const) { + /* If we're not generating the loop, we don't need to reset the + iterator. */ + if (cleanup_flags) + vec_safe_truncate (*cleanup_flags, 0); tree const_init = build_constructor (atype, const_vec); return build2 (INIT_EXPR, atype, obase, const_init); } diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-array23.C b/gcc/testsuite/g++.dg/cpp0x/initlist-array23.C new file mode 100644 index 00000000000..cda2afb9fcc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-array23.C @@ -0,0 +1,28 @@ +// PR c++/117985 +// { dg-do compile { target c++11 } } + +struct _Vector_impl { + constexpr + _Vector_impl() {} +}; +struct _Vector_base { + ~_Vector_base(); + _Vector_impl _M_impl; +}; +struct vector : private _Vector_base {}; +struct string { + string(); +}; +struct VEC { + vector pane{}; +}; +struct FOO { + VEC screen[1]{}; + string debug_name; +}; + +int +main () +{ + FOO{}; +} diff --git a/gcc/testsuite/g++.dg/cpp0x/initlist-array24.C b/gcc/testsuite/g++.dg/cpp0x/initlist-array24.C new file mode 100644 index 00000000000..7dda00d5c0b --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/initlist-array24.C @@ -0,0 +1,27 @@ +// PR c++/117985 +// { dg-do compile { target c++20 } } + +struct _Vector_impl { + constexpr _Vector_impl() {} +}; +struct _Vector_base { + constexpr ~_Vector_base() {} + _Vector_impl _M_impl; +}; +struct vector : private _Vector_base {}; +struct string { + string(); +}; +struct VEC { + vector pane{}; +}; +struct FOO { + VEC screen[1]{}; + string debug_name; +}; + +int +main () +{ + FOO{}; +} base-commit: 56f1863ade1bf416e09da305615ecb2ae04602a8 -- 2.47.1