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