c++: spec_hasher and TYPENAME_TYPE resolution [PR95223]
authorPatrick Palka <ppalka@redhat.com>
Wed, 20 May 2020 13:15:48 +0000 (09:15 -0400)
committerPatrick Palka <ppalka@redhat.com>
Wed, 20 May 2020 13:15:48 +0000 (09:15 -0400)
commit610ae2dbbf98a291782cb05c0fb31e056193e5e2
treef5edf193aa25d5def8c3a2ab87a7ac47912ca9dd
parent053dc901e0227bb62b65f3a8d7a9deccb61dffa1
c++: spec_hasher and TYPENAME_TYPE resolution [PR95223]

After enabling sanitization of the specialization tables, we are
triggering one of the hash table sanity checks in the below testcase.

The reason is that when looking up the specialization j<int> in the
type_specializations table, the sanity check finds that the existing
entry j<n<t>::m> compares equal to j<int> but hashes differently.

The discrepancy is due to structural_comptypes looking through
TYPENAME_TYPEs (via resolve_typename_type), something which
iterative_hash_template_arg doesn't do.  So the TYPENAME_TYPE n<t>::m is
considered equal to int, but the hashes of these two template arguments
are different.

It seems wrong for the result of a specialization table lookup to depend
on the current scope, so this patch makes structural_comptypes avoid
calling resolve_typename_type when comparing_specializations.

In order for the below testcase to deterministically trigger the
sanitization error without this patch, we also need to fix the location
of the call to hash_table::verify within hash_table::find_with_hash.

gcc/ChangeLog:

PR c++/95223
* hash-table.h (hash_table::find_with_hash): Move up the call to
hash_table::verify.

gcc/cp/ChangeLog:

PR c++/95223
* typeck.c (structural_comptypes): Don't perform
context-dependent resolution of TYPENAME_TYPEs when
comparing_specializations.

gcc/testsuite/ChangeLog:

PR c++/95223
* g++.dg/template/typename23.C: New test.
gcc/ChangeLog
gcc/cp/ChangeLog
gcc/cp/typeck.c
gcc/hash-table.h
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/typename23.C [new file with mode: 0644]