// The following code triggers "unimplemented ICE" when compiled with "-std=c++14"; // "-std=c++11" compiles fine. // g++ -std=c++14 test.cpp // Tested with: // g++ (GCC) 5.0.0 20150308 (experimental) // g++ (GCC) 5.0.0 20150323 (experimental) struct A { int x; char y; // Actually, short and bool (types smaller than int?) trigger this ICE too // Also: the problem doesn't occur if you put the smaller type first, e.g. "char x; int y;" A(int x) {} // custom ctor needed for ICE }; int main() { A a{0}, x{1}, y{2}; x = a; // OK y = a; // OK x = y = a; // ICE: sorry, unimplemented: unexpected AST of kind mem_ref // internal compiler error: in potential_constant_expression_1, at cp/constexpr.c:4432 return 0; } /* ./gcc/bin/g++ -std=c++14 test.cpp -o test test.cpp: In function ‘int main()’: test.cpp:20:13: sorry, unimplemented: unexpected AST of kind mem_ref x = y = a; // ICE: sorry, unimplemented: unexpected AST of kind mem_ref ^ test.cpp:20:13: internal compiler error: in potential_constant_expression_1, at cp/constexpr.c:4432 0x843238 potential_constant_expression_1 ../../gcc/cp/constexpr.c:4432 0x842eca potential_constant_expression_1 ../../gcc/cp/constexpr.c:4049 0x8423e5 potential_constant_expression_1 ../../gcc/cp/constexpr.c:4379 0x74c3d2 cp_parser_constant_expression ../../gcc/cp/parser.c:8672 0x74c0b4 cp_parser_assignment_expression ../../gcc/cp/parser.c:8434 0x74e80d cp_parser_expression ../../gcc/cp/parser.c:8569 0x74f0f6 cp_parser_expression_statement ../../gcc/cp/parser.c:9976 0x73c8b5 cp_parser_statement ../../gcc/cp/parser.c:9827 0x73d422 cp_parser_statement_seq_opt ../../gcc/cp/parser.c:10099 0x73d57b cp_parser_compound_statement ../../gcc/cp/parser.c:10053 0x75233b cp_parser_function_body ../../gcc/cp/parser.c:19185 0x75233b cp_parser_ctor_initializer_opt_and_function_body ../../gcc/cp/parser.c:19221 0x75cbaa cp_parser_function_definition_after_declarator ../../gcc/cp/parser.c:23464 0x75da23 cp_parser_function_definition_from_specifiers_and_declarator ../../gcc/cp/parser.c:23376 0x75da23 cp_parser_init_declarator ../../gcc/cp/parser.c:17055 0x75efbc cp_parser_simple_declaration ../../gcc/cp/parser.c:11592 0x75f313 cp_parser_block_declaration ../../gcc/cp/parser.c:11466 0x767879 cp_parser_declaration ../../gcc/cp/parser.c:11363 0x767afa cp_parser_declaration_seq_opt ../../gcc/cp/parser.c:11249 0x767e0f cp_parser_translation_unit ../../gcc/cp/parser.c:4100 Please submit a full bug report,
Confirmed. Btw, I wonder why we sorry here instead of simply treating it as non-constant...
Run till exit from #0 0x00000000012bf93a in build2_stat (code=MEM_REF, tt=<array_type 0x7ffff6a35f18>, arg0=<addr_expr 0x7ffff6a39760>, arg1=<integer_cst 0x7ffff6a33228>) at /space/rguenther/src/svn/trunk/gcc/tree.c:4385 0x00000000006f8b40 in build_over_call (cand=0x24f7aa0, flags=1, complain=3) at /space/rguenther/src/svn/trunk/gcc/cp/call.c:7456 7456 t = build2 (MODIFY_EXPR, void_type_node, Value returned is $9 = (tree_node *) 0x7ffff6a37758 (gdb) l 7451 array_type = build_array_type (char_type_node, 7452 build_index_type 7453 (size_binop (MINUS_EXPR, 7454 arg2, size_int (1)))); 7455 alias_set = build_int_cst (build_pointer_type (type), 0); 7456 t = build2 (MODIFY_EXPR, void_type_node, 7457 build2 (MEM_REF, array_type, arg0, alias_set), 7458 build2 (MEM_REF, array_type, arg, alias_set)); 7459 val = build2 (COMPOUND_EXPR, TREE_TYPE (to), t, to); so the C++ FE even builds this itself.
Ah, and that was me: 2011-08-12 Richard Guenther <rguenther@suse.de> * call.c (build_over_call): Instead of memcpy use an assignment of two MEM_REFs. which implements memcpy as *(char[n])ptr1 = *(char[n])ptr2; But we ask #4 0x000000000097fdb9 in potential_rvalue_constant_expression ( t=<compound_expr 0x7ffff6a377a8>) at /space/rguenther/src/svn/trunk/gcc/cp/constexpr.c:4478 (gdb) p debug_generic_expr (expression) MEM[(struct A *)&y] = MEM[(struct A *)(const struct A &) (const struct A *) &a];, y so I wonder why we look at the side-effects at all? That is, why does COMPOUND_EXPR handling not return false on side-effects early?
(In reply to Richard Biener from comment #3) > so I wonder why we look at the side-effects at all? That is, why does > COMPOUND_EXPR handling not return false on side-effects early? Because a call to a constexpr function has TREE_SIDE_EFFECTS; we don't know whether it's constant until we do the evaluation.
Fixed.
Author: jason Date: Thu Mar 26 17:58:39 2015 New Revision: 221699 URL: https://gcc.gnu.org/viewcvs?rev=221699&root=gcc&view=rev Log: PR c++/65525 * constexpr.c (potential_constant_expression_1): Handle MEM_REF. Added: trunk/gcc/testsuite/g++.dg/parse/assign1.C Modified: trunk/gcc/cp/ChangeLog trunk/gcc/cp/constexpr.c
Thanks!