On 04/09/16 16:08, Richard Biener wrote:
On September 4, 2016 12:33:02 PM GMT+02:00, Tom de Vries 
<tom_devr...@mentor.com> wrote:
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.

But how did it then work before the patch causing this?

Before the patch that introduced the attribute, rather than assigning the result of ix86_build_builtin_va_list_64 directly sysv_va_list_type_node, an intermediate build_variant_type_copy was used.

This had as consequence that the copy was named and not added to the cache, and that the original in the type cache remained unnamed.

Adding the build_variant_type_copy back fixes the ICE. But I'm not sure if that's a correct fix. The copy would have it's canonical type set to the original type. But if we'd search for the canonical type of the copy in the type cache, we wouldn't find it.

Thanks,
- Tom

Reply via email to