https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68763

--- Comment #13 from Jakub Jelinek <jakub at gcc dot gnu.org> ---
The reason for the weird behavior of build_method_type_directly are default
args.
We call this function with one argument list and return type etc., where one
argument type in TYPE_ARG_TYPES has TREE_PURPOSE some DEFAULT_ARG.  Then it is
called again on another argument list and return type, but all the types are
the same in there, the only difference is that the argument with default arg
has different DEFAULT_ARG (and obviously the TREE_LIST nodes aren't the same
either, but that is not the problem).  TREE_PURPOSE of TYPE_ARG_TYPES nodes is
ignored for hash value computation, the two nodes get the same hash value. 
But,
type_list_equal compares even the TREE_PURPOSE and determines the two
METHOD_TYPEs are not equal, so we create another METHOD_TYPE.  Next, we
in-place modify the TREE_PURPOSE in those two METHOD_TYPEs and they actually
end up being the same (well, not pointer equality, but simple_cst_equal kind of
equality).
So, because of the in-place modifications of the default argument, we now have
two different METHOD_TYPEs that compare equal and have the same hash value in
the hash table, and we get pretty randomly chosen one of those.

Now, the question is, do we use hash tables for the FUNCTION_TYPE/METHOD_TYPE
just as a way to decrease compiler memory usage (in that case what we do is
probably fine), or do we rely on it for other reasons, so that say pointer
equality can be used for the "same" function types (strip_typedefs and its
caller clearly relies on that, but perhaps that is a bug).  If we rely on it
for other reasons, then I'd be afraid we couldn't modify the default arguments
in place, so we'd need to include the TREE_PURPOSE in the hash value
(optionally) and build_method_type_directly again after we change the
TREE_PURPOSE, so in the end such change could result in more compiler memory
being used for the function/method types.

Reply via email to