Bug 65525 - [5 Regression] ICE: sorry, unimplemented: unexpected AST of kind mem_ref (-std=c++14, ICE: in potential_constant_expression_1, at cp/constexpr.c:4432)
Summary: [5 Regression] ICE: sorry, unimplemented: unexpected AST of kind mem_ref (-st...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 5.0
: P3 normal
Target Milestone: 5.0
Assignee: Jason Merrill
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2015-03-23 16:14 UTC by Marcin Sobieszczanski
Modified: 2015-03-27 09:36 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2015-03-24 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Marcin Sobieszczanski 2015-03-23 16:14:29 UTC
// 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,
Comment 1 Richard Biener 2015-03-24 10:13:41 UTC
Confirmed.

Btw, I wonder why we sorry here instead of simply treating it as non-constant...
Comment 2 Richard Biener 2015-03-24 10:15:25 UTC
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.
Comment 3 Richard Biener 2015-03-24 10:23:35 UTC
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?
Comment 4 Jason Merrill 2015-03-26 15:49:00 UTC
(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.
Comment 5 Jason Merrill 2015-03-26 17:58:54 UTC
Fixed.
Comment 6 Jason Merrill 2015-03-26 17:59:11 UTC
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
Comment 7 Roger Orr 2015-03-27 09:36:31 UTC
Thanks!