g++ version: 8.2.0 Trying to compile the following source causes internal compiler error: ------- #include <array> constexpr std::array<int, 256> prepare() { std::array<int, 256> r = {0}; for ( int i = 0; i < 6; ++i ) { r[i + 'a'] = r[i + 'A'] = i + 10; } return r; } int main() { auto v = prepare(); return 0; } ------- g++ -std=c++17 xx.cpp xx.cpp: In function ‘int main()’: xx.cpp:16:20: internal compiler error: Segmentation fault auto v = prepare();
Confirmed.
The current ICE started with r267253: 89336.C: In function ‘int main()’: 89336.C:16:20: internal compiler error: Segmentation fault 0x13ae0c0 crash_signal ../../gcc/toplev.c:326 0x89a0e1 initialized_type ../../gcc/cp/constexpr.c:2830 0x89a2eb init_subob_ctx ../../gcc/cp/constexpr.c:2864 0x89a8dc cxx_eval_bare_aggregate ../../gcc/cp/constexpr.c:2951 0x8a205e cxx_eval_constant_expression ../../gcc/cp/constexpr.c:4692 0x89a94d cxx_eval_bare_aggregate ../../gcc/cp/constexpr.c:2956 0x8a205e cxx_eval_constant_expression ../../gcc/cp/constexpr.c:4692 0x8a38ea cxx_eval_outermost_constant_expr ../../gcc/cp/constexpr.c:5077 0x8a454c maybe_constant_value(tree_node*, tree_node*, bool) ../../gcc/cp/constexpr.c:5309 0x8c2776 cp_fully_fold(tree_node*) ../../gcc/cp/cp-gimplify.c:2161 0xb73a19 split_nonconstant_init(tree_node*, tree_node*) ../../gcc/cp/typeck2.c:753 0xb7421d store_init_value(tree_node*, tree_node*, vec<tree_node*, va_gc, vl_embed>**, int) ../../gcc/cp/typeck2.c:876 0x9041c4 check_initializer ../../gcc/cp/decl.c:6491 0x90766d cp_finish_decl(tree_node*, tree_node*, bool, tree_node*, int) ../../gcc/cp/decl.c:7167 0xa0faa8 cp_parser_init_declarator ../../gcc/cp/parser.c:20327 0xa02a14 cp_parser_simple_declaration ../../gcc/cp/parser.c:13414 0xa025a5 cp_parser_block_declaration ../../gcc/cp/parser.c:13239 0xa01a00 cp_parser_declaration_statement ../../gcc/cp/parser.c:12844 0x9fdb1a cp_parser_statement ../../gcc/cp/parser.c:11169 0x9fe815 cp_parser_statement_seq_opt ../../gcc/cp/parser.c:11531 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions. but before that it ICEd also: 89336.C: In function ‘int main()’: 89336.C:16:20: internal compiler error: Segmentation fault 0x13ae0a2 crash_signal ../../gcc/toplev.c:326 0xb7348a split_nonconstant_init_1 ../../gcc/cp/typeck2.c:641 0xb7350c split_nonconstant_init_1 ../../gcc/cp/typeck2.c:652 0xb73a1b split_nonconstant_init(tree_node*, tree_node*) ../../gcc/cp/typeck2.c:755 0xb741ff store_init_value(tree_node*, tree_node*, vec<tree_node*, va_gc, vl_embed>**, int) ../../gcc/cp/typeck2.c:876 0x9041a6 check_initializer ../../gcc/cp/decl.c:6491 0x90764f cp_finish_decl(tree_node*, tree_node*, bool, tree_node*, int) ../../gcc/cp/decl.c:7167 0xa0fa8a cp_parser_init_declarator ../../gcc/cp/parser.c:20327 0xa029f6 cp_parser_simple_declaration ../../gcc/cp/parser.c:13414 0xa02587 cp_parser_block_declaration ../../gcc/cp/parser.c:13239 0xa019e2 cp_parser_declaration_statement ../../gcc/cp/parser.c:12844 0x9fdafc cp_parser_statement ../../gcc/cp/parser.c:11169 0x9fe7f7 cp_parser_statement_seq_opt ../../gcc/cp/parser.c:11531 0x9fe6ed cp_parser_compound_statement ../../gcc/cp/parser.c:11485 0xa13879 cp_parser_function_body ../../gcc/cp/parser.c:22405 0xa13a3d cp_parser_ctor_initializer_opt_and_function_body ../../gcc/cp/parser.c:22442 0xa1d7ec cp_parser_function_definition_after_declarator ../../gcc/cp/parser.c:27495 0xa1d619 cp_parser_function_definition_from_specifiers_and_declarator ../../gcc/cp/parser.c:27411 0xa0f2a1 cp_parser_init_declarator ../../gcc/cp/parser.c:20097 0xa029f6 cp_parser_simple_declaration ../../gcc/cp/parser.c:13414 Please submit a full bug report, with preprocessed source if appropriate. Please include the complete backtrace with any bug report. See <https://gcc.gnu.org/bugs/> for instructions.
r[i + 'a'] = i + 10; r[i + 'A'] = i + 10; or r[i + 'a'] = i + 10; r[i + 'A'] = r[i + 'a']; doesn't ICE.
Reduced testcase: template <typename T, int N> struct A { T a[N]; constexpr T &operator[] (int x) { return a[x]; } }; constexpr A<int, 16> foo () { A<int, 16> r{}; for (int i = 0; i < 6; ++i) r[i + 8] = r[i] = i; return r; } auto x = foo (); Started to ICE with r217670, before that it has been accepted for a couple of revisions and before that rejected.
The ICE actually isn't when processing the loop, but later on when processing the VIEW_CONVERT_EXPR<struct A>({.a={0, 1, 2, 3, 4, 5, [8]=1, 2, 3, 4, 5, }}); expression. When using { r[i] = i; r[i + 8] = i; } as the loop body, I instead get: {.a={0, 1, 2, 3, 4, 5, [8]=0, 1, 2, 3, 4, 5}} In the bogus one, [8] doesn't have the value 0 but 1 and all the values are shifted by 1, with [13] having NULL value, just non-NULL purpose.
Created attachment 45706 [details] gcc9-pr89336.patch Untested fix. Pointing a pointer into a middle of vector that might be reallocated or where new elements might be added before the one to which we store (and that addition memmoves all the rest upwards) is dangerous. This patch should fix that, except that it doesn't fix union handling. I think e.g. constexpr int foo () { union U { int a; long b; }; union V { union U u; short v; }; V w {}; w.u.a = w.v = w.u.b = 5L; return w.u.a; } static_assert (foo () == 5, ""); ICEs with it (previously it would fail). Is the testcase valid C++? clang++ rejects it. The question is when exactly becomes a union member active on the assignment, if only after evaluating the rhs, or it first becomes active member, then rhs is evaluated.
Author: jason Date: Tue Feb 19 01:01:50 2019 New Revision: 269003 URL: https://gcc.gnu.org/viewcvs?rev=269003&root=gcc&view=rev Log: PR c++/89336 - multiple stores in constexpr stmt. If we evaluate the RHS in the context of the LHS, that evaluation might change the LHS in ways that mess with being able to store the value later. So for assignment or scalar values, evaluate the RHS first. * constexpr.c (cxx_eval_store_expression): Preevaluate scalar or assigned value. Added: trunk/gcc/testsuite/g++.dg/cpp1y/constexpr-89336-1.C trunk/gcc/testsuite/g++.dg/cpp1y/constexpr-89336-2.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/constexpr.c
Author: jakub Date: Wed Feb 20 21:16:27 2019 New Revision: 269052 URL: https://gcc.gnu.org/viewcvs?rev=269052&root=gcc&view=rev Log: PR c++/89336 * constexpr.c (cxx_eval_store_expression): Diagnose changing of active union member for -std=c++17 and earlier. * g++.dg/cpp1y/constexpr-89336-3.C: New test. Added: trunk/gcc/testsuite/g++.dg/cpp1y/constexpr-89336-3.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/constexpr.c trunk/gcc/testsuite/ChangeLog
Fixed?
Assuming fixed.