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 <[email protected]>
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 <[email protected]>
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); }