------- Comment #3 from rguenth at gcc dot gnu dot org 2007-07-05 19:06 ------- We compare two pointer-to-method types that "look" the same:
Breakpoint 3, useless_type_conversion_p (outer_type=0xb7d869b4, inner_type=0xb7d866c0) at /home/richard/src/trunk2/gcc/tree-ssa.c:917 917 inner_type = TYPE_MAIN_VARIANT (inner_type); QWidget:: * QWidget:: * (gdb) call debug_tree (outer_type) <pointer_type 0xb7d869b4 type <method_type 0xb7d86360 type <void_type 0xb7cc15e8 void VOID align 8 symtab 0 alias set -1 canonical type 0xb7cc15e8 pointer_to_this <pointer_type 0xb7cc1654>> QI size <integer_cst 0xb7ca84b4 constant invariant 8> unit size <integer_cst 0xb7ca84d0 constant invariant 1> align 8 symtab 0 alias set -1 canonical type 0xb7d86438 method basetype <record_type 0xb7d860d8 QWidget> arg-types <tree_list 0xb7d32dac value <pointer_type 0xb7d863cc> chain <tree_list 0xb7d32d74 purpose <integer_cst 0xb7ca8c08 constant invariant 1> value <boolean_type 0xb7cba57c bool> chain <tree_list 0xb7ca8e70 value <void_type 0xb7cc15e8 void>>>> pointer_to_this <pointer_type 0xb7d869b4>> unsigned SI size <integer_cst 0xb7ca863c type <integer_type 0xb7cba06c bit_size_type> constant invariant 32> unit size <integer_cst 0xb7ca8428 type <integer_type 0xb7cba000 unsigned int> constant invariant 4> align 32 symtab 0 alias set -1 canonical type 0xb7d866c0> (gdb) call debug_tree (inner_type) <pointer_type 0xb7d866c0 type <method_type 0xb7d86438 type <void_type 0xb7cc15e8 void VOID align 8 symtab 0 alias set -1 canonical type 0xb7cc15e8 pointer_to_this <pointer_type 0xb7cc1654>> QI size <integer_cst 0xb7ca84b4 constant invariant 8> unit size <integer_cst 0xb7ca84d0 constant invariant 1> align 8 symtab 0 alias set -1 canonical type 0xb7d86438 method basetype <record_type 0xb7d860d8 QWidget> arg-types <tree_list 0xb7d32de4 value <pointer_type 0xb7d863cc> chain <tree_list 0xb7d32dc8 value <boolean_type 0xb7cba57c bool> chain <tree_list 0xb7ca8e70 value <void_type 0xb7cc15e8 void>>>> pointer_to_this <pointer_type 0xb7d866c0>> sizes-gimplified unsigned SI size <integer_cst 0xb7ca863c type <integer_type 0xb7cba06c bit_size_type> constant invariant 32> unit size <integer_cst 0xb7ca8428 type <integer_type 0xb7cba000 unsigned int> constant invariant 4> align 32 symtab 0 alias set -1 canonical type 0xb7d866c0> (note they have the same canonical types, for both the pointer and the pointed-to type. note they both have their alias set not computed.) Now at the point we verify if those pointer types are compatible we check /* Do not lose casts between pointers with different TYPE_REF_CAN_ALIAS_ALL setting or alias sets. */ if ((TYPE_REF_CAN_ALIAS_ALL (inner_type) != TYPE_REF_CAN_ALIAS_ALL (outer_type)) || (get_alias_set (TREE_TYPE (inner_type)) != get_alias_set (TREE_TYPE (outer_type)))) return false; which calls get_alias_set on both pointed-to types which (surprisingly?) returns 2 for one and 3 for the other one. Because, while we specialize FUNCTION_TYPE /* There are no objects of FUNCTION_TYPE, so there's no point in using up an alias set for them. (There are, of course, pointers and references to functions, but that's different.) */ else if (TREE_CODE (t) == FUNCTION_TYPE) set = 0; we do not so for METHOD_TYPE, which looks like an omission. Also it looks like in useless_type_conversion_p we can move the canonical types check to the top and use it for all types. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=32639