[Bug c++/90938] [9/10 Regression] Initializing array with {1} works, but not {0}
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938 --- Comment #13 from CVS Commits --- The master branch has been updated by Martin Sebor : https://gcc.gnu.org/g:cb2409c60aeff498064346f85165531a3bbead14 commit r10-7034-gcb2409c60aeff498064346f85165531a3bbead14 Author: Martin Sebor Date: Wed Mar 4 18:19:31 2020 -0700 PR c++/90938 - Initializing array with {1} works but not {0} gcc/cp/ChangeLog: PR c++/90938 * tree.c (type_initializer_zero_p): Fail for structs initialized with non-structs. gcc/testsuite/ChangeLog: PR c++/90938 * g++.dg/init/array55.C: New test. * g++.dg/init/array56.C: New test. * g++.dg/cpp2a/nontype-class33.C: New test.
[Bug c++/90938] [9/10 Regression] Initializing array with {1} works, but not {0}
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938 Martin Sebor changed: What|Removed |Added Keywords||patch --- Comment #12 from Martin Sebor --- Patch: https://gcc.gnu.org/ml/gcc-patches/2020-02/msg00676.html
[Bug c++/90938] [9/10 Regression] Initializing array with {1} works, but not {0}
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938 Jason Merrill changed: What|Removed |Added CC||jason at gcc dot gnu.org --- Comment #11 from Jason Merrill --- Any update?
[Bug c++/90938] [9/10 Regression] Initializing array with {1} works, but not {0}
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938 --- Comment #10 from Jakub Jelinek --- There is no cutoff for 9.x (well, in about 2 years from now the branch will be closed), but the branch is used by people in the wild, so especially for regressions from recent releases the sooner it is fixed the better. Of course assuming the fix is safe.
[Bug c++/90938] [9/10 Regression] Initializing array with {1} works, but not {0}
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938 --- Comment #9 from Martin Sebor --- I plan to submit a patch for GCC 10 and (hopefully) also GCC 9.x. What's the cutoff for 9?
[Bug c++/90938] [9/10 Regression] Initializing array with {1} works, but not {0}
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938 Jakub Jelinek changed: What|Removed |Added CC||jakub at gcc dot gnu.org --- Comment #8 from Jakub Jelinek --- Martin, any progress here?
[Bug c++/90938] [9/10 Regression] Initializing array with {1} works, but not {0}
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938 Jakub Jelinek changed: What|Removed |Added Target Milestone|9.2 |9.3 --- Comment #7 from Jakub Jelinek --- GCC 9.2 has been released.
[Bug c++/90938] [9/10 Regression] Initializing array with {1} works, but not {0}
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938 Richard Biener changed: What|Removed |Added Priority|P3 |P2
[Bug c++/90938] [9/10 Regression] Initializing array with {1} works, but not {0}
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938 --- Comment #6 from Jonathan Wakely --- (In reply to Martin Sebor from comment #4) > Yes, the problem is that triviality isn't sufficient to decide whether the > transformation can be enabled. I think we need to check whether the type > has a trivial default ctor. Maybe like this: > > --- gcc/cp/decl.c (revision 272482) > +++ gcc/cp/decl.c (working copy) > @@ -5853,7 +5853,7 @@ reshape_init_array_1 (tree elt_type, tree max_inde > break; > } > > - if (sized_array_p && trivial_type_p (elt_type)) > + if (sized_array_p && type_has_nontrivial_default_init (elt_type)) Is that backwards? That checks whether it has a non-trivial default ctor. But I think that's still wrong, as comment 3 shows, the transformation can go from calling a non-trivial ctor to something completely different. If the type has any user-defined constructors then you can't assume that a zero initializer is default init. Also, the testcase from PR 90947 is miscompiled with an array of pointers, which are definitely trivial and don't have a non-trivial default ctor. #include #include static const char *vector_swizzle(int vecsize, int index) { static const char *swizzle[4][4] = { { ".x", ".y", ".z", ".w" }, { ".xy", ".yz", ".zw", nullptr }, { ".xyz", ".yzw", nullptr, nullptr }, { "", nullptr, nullptr, nullptr }, }; assert(vecsize >= 1 && vecsize <= 4); assert(index >= 0 && index < 4); assert(swizzle[vecsize - 1][index]); return swizzle[vecsize - 1][index]; } int main() { puts(vector_swizzle(4, 0)); }
[Bug c++/90938] [9/10 Regression] Initializing array with {1} works, but not {0}
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938 Jonathan Wakely changed: What|Removed |Added CC||maister at archlinux dot us --- Comment #5 from Jonathan Wakely --- *** Bug 90947 has been marked as a duplicate of this bug. ***
[Bug c++/90938] [9/10 Regression] Initializing array with {1} works, but not {0}
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938 Martin Sebor changed: What|Removed |Added Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |msebor at gcc dot gnu.org --- Comment #4 from Martin Sebor --- Yes, the problem is that triviality isn't sufficient to decide whether the transformation can be enabled. I think we need to check whether the type has a trivial default ctor. Maybe like this: --- gcc/cp/decl.c (revision 272482) +++ gcc/cp/decl.c (working copy) @@ -5853,7 +5853,7 @@ reshape_init_array_1 (tree elt_type, tree max_inde break; } - if (sized_array_p && trivial_type_p (elt_type)) + if (sized_array_p && type_has_nontrivial_default_init (elt_type)) { /* Strip trailing zero-initializers from an array of a trivial type of known size. They are redundant and get in the way
[Bug c++/90938] [9/10 Regression] Initializing array with {1} works, but not {0}
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938 --- Comment #3 from Jonathan Wakely --- Not a dup, because turning {0, 0} into {} is still wrong even for trivial classes: struct X { X() = default; X(int n) : n(n+1) { } int n; }; static_assert(__is_trivial(X), ""); int main() { X x[1] { 1 }; // OK if (x->n != 2) __builtin_abort(); X y[1] { 0 }; if (y->n != 1) __builtin_abort(); } Aborted (core dumped) The array element has a non-empty initializer, so must call the X(int) constructor, which has very different semantics from the default constructor. An {0} initializer could be a null pointer constant too: struct X { X() = default; X(int* p) : p(p ? p : new int(1)) { } int* p; }; static_assert(__is_trivial(X), ""); int main() { X x[1] { nullptr }; // OK if (*x->p != 1) __builtin_abort(); X y[1] { 0 }; if (*y->p != 1) __builtin_abort(); } Segmentation fault (core dumped)
[Bug c++/90938] [9/10 Regression] Initializing array with {1} works, but not {0}
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938 Jonathan Wakely changed: What|Removed |Added Depends on||85723 --- Comment #2 from Jonathan Wakely --- The class X should not be trivial, see https://wg21.link/cwg1496 So maybe this is a dup of Bug 85723 Referenced Bugs: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=85723 [Bug 85723] [C++17][DR 1496] __is_trivial intrinsic fails with no trivial non-deleted default c'tor
[Bug c++/90938] [9/10 Regression] Initializing array with {1} works, but not {0}
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938 --- Comment #1 from Jonathan Wakely --- (In reply to Jonathan Wakely from comment #0) > (write_expression): Trim trailing zero-initializers from arrays > of trivial type. I assume this is the problem. {} will default construct, but {0} does not, and should not be turned into default construction.
[Bug c++/90938] [9/10 Regression] Initializing array with {1} works, but not {0}
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938 Jonathan Wakely changed: What|Removed |Added Status|UNCONFIRMED |NEW Last reconfirmed||2019-06-19 Known to work||8.3.0 Target Milestone|--- |9.2 Ever confirmed|0 |1 Known to fail||10.0, 9.1.0