Summary: | [8/9 Regression] error initializing a constexpr array of a struct with const member | ||
---|---|---|---|
Product: | gcc | Reporter: | Martin Sebor <msebor> |
Component: | c++ | Assignee: | Jason Merrill <jason> |
Status: | RESOLVED FIXED | ||
Severity: | normal | CC: | jason, webrown.cpp |
Priority: | P2 | Keywords: | rejects-valid |
Version: | 9.0 | ||
Target Milestone: | 8.4 | ||
See Also: |
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90938 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=90947 |
||
Host: | Target: | ||
Build: | Known to work: | 4.8.5 | |
Known to fail: | 10.0, 4.9.1, 5.5.0, 6.4.0, 7.4.0, 8.3.0, 9.1.0 | Last reconfirmed: | 2020-01-28 00:00:00 |
Description
Martin Sebor
2019-06-20 20:12:13 UTC
Actually, I don't think this is related to r270155. When the test case is modified as shown below it fails to compile even prior to the change and all the way to GCC 4.9. It is accepted by GCC 4.8. It needs -std=c++11: #define assert(expr) static_assert (expr, #expr) struct S { const char a[2]; }; constexpr struct S a[1][1][1] = { }; assert ('\0' == *a[0][0][0].a); t.C:7:29: error: use of deleted function ‘S::S()’ 7 | assert ('\0' == *a[0][0][0].a); | ^ t.C:1:37: note: in definition of macro ‘assert’ 1 | #define assert(expr) static_assert (expr, #expr) | ^~~~ t.C:3:10: note: ‘S::S()’ is implicitly deleted because the default definition would be ill-formed: 3 | struct S { const char a[2]; }; | ^ t.C:3:10: error: uninitialized const member in ‘struct S’ t.C:3:25: note: ‘const char S::a [2]’ should be initialized 3 | struct S { const char a[2]; }; | ^ t.C:7:31: error: use of deleted function ‘S::S()’ 7 | assert ('\0' == *a[0][0][0].a); | ^ t.C:7:14: error: non-constant condition for static assertion 7 | assert ('\0' == *a[0][0][0].a); | ~~~~~^~~~~~~~~~~~~~~~ t.C:1:37: note: in definition of macro ‘assert’ 1 | #define assert(expr) static_assert (expr, #expr) | ^~~~ t.C:7:14: error: use of deleted function ‘S::S()’ 7 | assert ('\0' == *a[0][0][0].a); | ~~~~~^~~~~~~~~~~~~~~~ t.C:1:37: note: in definition of macro ‘assert’ 1 | #define assert(expr) static_assert (expr, #expr) | ^~~~ The compilation error was introduced in r209934 (gcc 5.0.0) via: PR c++/60980 * init.c (build_value_init): Don't try to call an array constructor. Prior to that GCC fails with an ICE on this test case. The ICE was in turn introduced in r203985 (gcc 4.9.0): In C++11 a trivial [cd]tor might not be callable. * class.c (user_provided_p): A function deleted on its declation in the class is not user-provided. (type_build_ctor_call): Also force a ctor call if we might have a deleted or private trivial ctor. (type_build_dtor_call): New. (deduce_noexcept_on_destructors): Remove obsolete code. * cp-tree.h: Declare type_build_dtor_call. * decl.c (expand_static_init): Make sure trivial dtors are callable. (cxx_maybe_build_cleanup): Likewise. * except.c (build_throw): Likewise. * init.c (build_value_init): Handle trivial but not callable ctors. (perform_target_ctor): Make sure trivial dtor is callable. (perform_member_init): Likewise. (expand_cleanup_for_base): Likewise. (build_vec_delete_1): Likewise. (build_delete): Likewise. (push_base_cleanups): Likewise. (build_new_1): Avoid redundant error. * method.c (synthesized_method_walk): Can't ever exit early in C++11. Always process the subobject destructor. * semantics.c (finish_compound_literal): Make sure trivial dtor is callable. * typeck2.c (split_nonconstant_init): Likewise. Before this change the test case was accepted. The master branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:0712ea6313bc44f9ae8feb235c1b02c92cdd0527 commit r10-6437-g0712ea6313bc44f9ae8feb235c1b02c92cdd0527 Author: Jason Merrill <jason@redhat.com> Date: Tue Feb 4 15:54:17 2020 -0500 c++: Fix constexpr vs. omitted aggregate init. Value-initialization is importantly different from {}-initialization for this testcase, where the former calls the deleted S constructor and the latter initializes S happily. PR c++/90951 * constexpr.c (cxx_eval_array_reference): {}-initialize missing elements instead of value-initializing them. Fixed for GCC 10 so far. The releases/gcc-8 branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:300d219af336436fbb58043db193f54d2a1b4b49 commit r8-10054-g300d219af336436fbb58043db193f54d2a1b4b49 Author: Jason Merrill <jason@redhat.com> Date: Mon Feb 24 16:22:45 2020 -0500 c++: Fix constexpr vs. omitted aggregate init. Value-initialization is importantly different from {}-initialization for this testcase, where the former calls the deleted S constructor and the latter initializes S happily. gcc/cp/ChangeLog 2020-02-24 Jason Merrill <jason@redhat.com> PR c++/90951 * constexpr.c (cxx_eval_array_reference): {}-initialize missing elements instead of value-initializing them. The releases/gcc-9 branch has been updated by Jason Merrill <jason@gcc.gnu.org>: https://gcc.gnu.org/g:c51ac41714469104ee6120db3eedfb0964290502 commit r9-8292-gc51ac41714469104ee6120db3eedfb0964290502 Author: Jason Merrill <jason@redhat.com> Date: Wed Feb 26 13:03:23 2020 -0500 c++: Fix constexpr vs. omitted aggregate init. Value-initialization is importantly different from {}-initialization for this testcase, where the former calls the deleted S constructor and the latter initializes S happily. gcc/cp/ChangeLog 2020-02-26 Jason Merrill <jason@redhat.com> PR c++/90951 * constexpr.c (cxx_eval_array_reference): {}-initialize missing elements instead of value-initializing them. And 8.4 and 9.3. |