On 04/09/16 08:12, Richard Biener wrote:
On September 3, 2016 5:23:35 PM GMT+02:00, Tom de Vries 
<tom_devr...@mentor.com> wrote:
>Hi,
>
>this patch fixes a c++ ICE, a p1 6/7 regression.
>
>
>Consider test.C:
>...
>void bar (__builtin_va_list &);
>
>struct c
>{
>   operator const __builtin_va_list &();
>   operator __builtin_va_list &();
>};
>
>void
>foo (void) {
>   struct c c1;
>
>   bar (c1);
>}
>...
>
>The compiler ICEs as follows:
>...
>test.C: In function ‘void foo()’:
>test.C:13:10: internal compiler error: canonical types differ for
>identical types __va_list_tag [1] and __va_list_tag [1]
>    bar (c1);
>           ^
>comptypes(tree_node*, tree_node*, int)
>    src/gcc/cp/typeck.c:1430
>reference_related_p(tree_node*, tree_node*)
>    src/gcc/cp/call.c:1415
>reference_binding
>    src/gcc/cp/call.c:1559
>implicit_conversion
>    src/gcc/cp/call.c:1805
>build_user_type_conversion_1
>    src/gcc/cp/call.c:3776
>reference_binding
>    src/gcc/cp/call.c:1664
>implicit_conversion
>    src/gcc/cp/call.c:1805
>add_function_candidate
>    src/gcc/cp/call.c:2141
>add_candidates
>    src/gcc/cp/call.c:5394
>perform_overload_resolution
>    src/gcc/cp/call.c:4066
>build_new_function_call(tree_node*, vec<tree_node*, va_gc, vl_embed>**,
>   bool, int)
>    src/gcc/cp/call.c:4143
>finish_call_expr(tree_node*, vec<tree_node*, va_gc, vl_embed>**, bool,
>   bool, int)
>    src/gcc/cp/semantics.c:2440
>...
>
>The regression is caused by the commit for PR70955, that adds a
>"sysv_abi va_list" attribute to the struct in the va_list type (which
>is
>an array of one of struct).
>
>The ICE in comptypes happens as follows: we're comparing two versions
>of
>va_list type (with identical array element type), each with the
>canonical type set to themselves. Since the types are considered
>identical, they're supposed to have identical canonical types, which is

Did you figure out why they are not assigned the same canonical type?

When constructing the first type in ix86_build_builtin_va_list_64, it's cached.

When constructing the second type in build_array_type_1 (with call stack: grokdeclarator -> cp_build_qualified_type_real -> build_cplus_array_type -> build_cplus_array_type -> build_array_type -> build_array_type_1), we call type_hash_canon.

But the cached type has name __builtin_sysv_va_list, and the new type has no name, so we hit the clause 'TYPE_NAME (a->type) != TYPE_NAME (b->type)' in type_cache_hasher::equal.

Consequently, TYPE_CANONICAL for the new type remain set to self.

Thanks,
- Tom

Reply via email to