Hi, On 07/22/2013 11:38 PM, Jason Merrill wrote:
I guess ptr_reasonably_similar should return false if one of the target types is incomplete.
Thanks.
The below passes testing on x86_64-linux. I'm also taking the chance to change the return type to bool, consistently with comptypes, error_type_p, etc.
A slightly less conservative version just doing: if (!COMPLETE_TYPE_P (to) || !COMPLETE_TYPE_P (from)) return false; also passes testing. Thanks! Paolo. /////////////////////////////
/cp 2013-07-23 Paolo Carlini <paolo.carl...@oracle.com> PR c++/57942 * typeck.c (ptr_reasonably_similar): Return false if one of the target types is incomplete; return a bool, not an int. * cp-tree.h (ptr_reasonably_similar): Adjust declaration. /testsuite 2013-07-23 Paolo Carlini <paolo.carl...@oracle.com> PR c++/57942 * g++.dg/inherit/pr57942.C: New.
Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 201148) +++ cp/cp-tree.h (working copy) @@ -6022,7 +6022,7 @@ extern tree convert_for_initialization (tree, tre extern int comp_ptr_ttypes (tree, tree); extern bool comp_ptr_ttypes_const (tree, tree); extern bool error_type_p (const_tree); -extern int ptr_reasonably_similar (const_tree, const_tree); +extern bool ptr_reasonably_similar (const_tree, const_tree); extern tree build_ptrmemfunc (tree, tree, int, bool, tsubst_flags_t); extern int cp_type_quals (const_tree); Index: cp/typeck.c =================================================================== --- cp/typeck.c (revision 201148) +++ cp/typeck.c (working copy) @@ -8599,10 +8599,10 @@ error_type_p (const_tree type) } } -/* Returns 1 if to and from are (possibly multi-level) pointers to the same +/* Returns true if to and from are (possibly multi-level) pointers to the same type or inheritance-related types, regardless of cv-quals. */ -int +bool ptr_reasonably_similar (const_tree to, const_tree from) { for (; ; to = TREE_TYPE (to), from = TREE_TYPE (from)) @@ -8614,8 +8614,11 @@ ptr_reasonably_similar (const_tree to, const_tree return !error_type_p (to); if (TREE_CODE (to) != TREE_CODE (from)) - return 0; + return false; + if (COMPLETE_TYPE_P (to) != COMPLETE_TYPE_P (from)) + return false; + if (TREE_CODE (from) == OFFSET_TYPE && comptypes (TYPE_OFFSET_BASETYPE (to), TYPE_OFFSET_BASETYPE (from), @@ -8624,11 +8627,11 @@ ptr_reasonably_similar (const_tree to, const_tree if (TREE_CODE (to) == VECTOR_TYPE && vector_types_convertible_p (to, from, false)) - return 1; + return true; if (TREE_CODE (to) == INTEGER_TYPE && TYPE_PRECISION (to) == TYPE_PRECISION (from)) - return 1; + return true; if (TREE_CODE (to) == FUNCTION_TYPE) return !error_type_p (to) && !error_type_p (from); Index: testsuite/g++.dg/inherit/pr57942.C =================================================================== --- testsuite/g++.dg/inherit/pr57942.C (revision 0) +++ testsuite/g++.dg/inherit/pr57942.C (working copy) @@ -0,0 +1,7 @@ +// PR c++/57942 + +template<typename T> struct S { typename T::error type; }; +struct X {}; +void f(S<int>*); +void f(...); +void g() { f((X*)0); }