8.0.min.ii:15: error: non-trivial conversion at assignment struct { X:: * const __pfn; long int __delta; } * const * struct { X:: * const __pfn; long int __delta; } * const & __ptr = __ptr.24 which is gimplified from the INIT_EXPR __ptr = (struct { X:: * const __pfn; long int __delta; } * const *) _M_access ((union _Any_data *) __source) where __ptrs type is structurally equivalent to the type the _M_access return value is converted to, but it has no relationship to it. The backtrace where this INIT_EXPR is created from is #0 build2_stat (code=INIT_EXPR, tt=0x2b9977879270, arg0=0x2b997792abb0, arg1=0x2b99778c2440) at /space/rguenther/src/svn/pointer_plus/gcc/tree.c:3064 #1 0x00000000004faa41 in split_nonconstant_init (dest=0x2b997792abb0, init=0x2b99778c2440) at /space/rguenther/src/svn/pointer_plus/gcc/cp/typeck2.c:553 #2 0x00000000004faea8 in store_init_value (decl=0x2b997792abb0, init=0x2b99778c2440) at /space/rguenther/src/svn/pointer_plus/gcc/cp/typeck2.c:626 #3 0x0000000000445eaf in check_initializer (decl=0x2b997792abb0, init=0x2b99778c2440, flags=0, cleanup=0x7fff34377270) at /space/rguenther/src/svn/pointer_plus/gcc/cp/decl.c:4892 #4 0x0000000000448f10 in cp_finish_decl (decl=0x2b997792abb0, init=0x2b99778c2440, init_const_expr_p=0 '\0', asmspec_tree=0x0, flags=0) at /space/rguenther/src/svn/pointer_plus/gcc/cp/decl.c:5291 #5 0x00000000004498e4 in finish_decl (decl=0x2b997792abb0, init=0x2b99778c2440, asmspec_tree=0x0) at /space/rguenther/src/svn/pointer_plus/gcc/cp/decl.c:5452 #6 0x00000000004c4289 in tsubst_expr (t=0x2b9977823480, args=0x2b9977717510, complain=tf_warning_or_error, in_decl=0x2b9977815d00, integral_constant_expression_p=0 '\0') at /space/rguenther/src/svn/pointer_plus/gcc/cp/pt.c:9850 #7 0x00000000004c3353 in tsubst_expr (t=0x2b997780f930, args=0x2b9977717510, ) at /space/rguenther/src/svn/pointer_plus/gcc/cp/pt.c:9771 #8 0x00000000004c5877 in tsubst_expr (t=0x2b997780c7d0, args=0x2b9977717510, complain=tf_warning_or_error, in_decl=0x2b9977815d00, integral_constant_expression_p=0 '\0') at /space/rguenther/src/svn/pointer_plus/gcc/cp/pt.c:9912 #9 0x00000000004ee15b in instantiate_decl (d=0x2b997791bf00, defer_ok=0, expl_inst_class_mem_p=0 '\0') at /space/rguenther/src/svn/pointer_plus/gcc/cp/pt.c:14415 #10 0x00000000004eea19 in instantiate_pending_templates (retries=0) at /space/rguenther/src/svn/pointer_plus/gcc/cp/pt.c:14520 #11 0x000000000054d6b0 in cp_write_global_declarations () at /space/rguenther/src/svn/pointer_plus/gcc/cp/decl2.c:3057 #12 0x0000000000a71ed6 in compile_file () at /space/rguenther/src/svn/pointer_plus/gcc/toplev.c:1057 #13 0x0000000000a73aa8 in do_compile () at /space/rguenther/src/svn/pointer_plus/gcc/toplev.c:2151 #14 0x0000000000a73b0c in toplev_main (argc=15, argv=0x7fff3437a0f8) at /space/rguenther/src/svn/pointer_plus/gcc/toplev.c:2183 #15 0x00000000006f17f3 in main (argc=15, argv=0x7fff3437a0f8) at /space/rguenther/src/svn/pointer_plus/gcc/main.c:35 The strange thing is that w/o -fstrict-aliasing only the trees of other functions than _M_get_pointer are changed (they get some change_dynamic_type expressions).
Created attachment 13960 [details] testcase (slightly reduced from tr1/3_function_objects/function/8.cc)
./cc1plus -fpreprocessed 8.0.min.ii -quiet -dumpbase 8.cc -auxbase 8 -version -fmessage-length=0 -o /dev/null -std=c++0x -fstrict-aliasing
Created attachment 13962 [details] testcase (more reduced)
break build2_stat if code == INIT_EXPR && !useless_type_conversion_p (arg0->common.type, arg1->common.type) and you reach the offending tree build.
With -fstrict-aliasing we claim the conversion is neccessary because the pointed to alias sets of the two pointers are different. For -fno-strict-aliasing the frontend later says via the langhook that the two structures are compatible. Now, both pointer-to-member function structures get assigned alias set zero anyway from cxx_get_alias_set, but pointers to such structures get their own alias set. Index: cp-objcp-common.c =================================================================== --- cp-objcp-common.c (revision 126911) +++ cp-objcp-common.c (working copy) @@ -45,7 +45,9 @@ cxx_get_alias_set (tree t) return get_alias_set (TYPE_CONTEXT (t)); /* Punt on PMFs until we canonicalize functions properly. */ - if (TYPE_PTRMEMFUNC_P (t)) + if (TYPE_PTRMEMFUNC_P (t) + || (POINTER_TYPE_P (t) + && TYPE_PTRMEMFUNC_P (TREE_TYPE (t)))) return 0; return c_common_get_alias_set (t); get's this case "working". Of course it may be time to "canonicalize functions properly".
This was fixed by 2007-08-20 Richard Guenther <rguenther@suse.de> PR c++/22369 PR c++/22451 * call.c (build_new_method_call): Convert initializer to the basetype. * init.c (build_aggr_init): Do not fiddle with types. (build_vec_delete_1): Use correct type for POINTER_PLUS_EXPR. * except.c (build_throw): Do not drop qualifiers for the pointer type. * typeck.c (get_member_function_from_ptrfunc): Do not fiddle with types, instead convert. (build_ptrmemfunc1): Convert to the target type for initialization. (gfc_trans_allocate): Convert result to target type. * cp-objcp-common.c (cxx_get_alias_set): Pointers to pointer-to-member structures shall have alias set zero as well.