From 8797ee50169efee927b57dbedf1ec6c41c197a76 Mon Sep 17 00:00:00 2001 From: paolo Date: Wed, 24 Jul 2013 08:35:54 +0000 Subject: [PATCH] /cp 2013-07-24 Paolo Carlini PR c++/57942 * typeck.c (ptr_reasonably_similar): Use COMPARE_STRICT 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-24 Paolo Carlini PR c++/57942 * g++.dg/inherit/pr57942.C: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@201201 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/cp/ChangeLog | 7 +++++++ gcc/cp/cp-tree.h | 2 +- gcc/cp/typeck.c | 21 +++++++++++++-------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/g++.dg/inherit/pr57942.C | 9 +++++++++ 5 files changed, 35 insertions(+), 9 deletions(-) create mode 100644 gcc/testsuite/g++.dg/inherit/pr57942.C diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 862e8597086..f7052cb54aa 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,10 @@ +2013-07-24 Paolo Carlini + + PR c++/57942 + * typeck.c (ptr_reasonably_similar): Use COMPARE_STRICT if one of + the target types is incomplete; return a bool, not an int. + * cp-tree.h (ptr_reasonably_similar): Adjust declaration. + 2013-07-22 Paolo Carlini * cp-tree.h (DERIVED_FROM_P): Pass tf_none to lookup_base, not diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 459c0e27ef3..4a2271fcce0 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6022,7 +6022,7 @@ extern tree convert_for_initialization (tree, tree, tree, int, 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); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index ef781a3c644..6f330559adf 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -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,7 +8614,7 @@ ptr_reasonably_similar (const_tree to, const_tree from) return !error_type_p (to); if (TREE_CODE (to) != TREE_CODE (from)) - return 0; + return false; if (TREE_CODE (from) == OFFSET_TYPE && comptypes (TYPE_OFFSET_BASETYPE (to), @@ -8624,19 +8624,24 @@ ptr_reasonably_similar (const_tree to, const_tree from) 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); if (!TYPE_PTR_P (to)) - return comptypes - (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), - COMPARE_BASE | COMPARE_DERIVED); + { + /* When either type is incomplete avoid DERIVED_FROM_P, + which may call complete_type (c++/57942). */ + bool b = !COMPLETE_TYPE_P (to) || !COMPLETE_TYPE_P (from); + return comptypes + (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), + b ? COMPARE_STRICT : COMPARE_BASE | COMPARE_DERIVED); + } } } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 7b24942e113..1cfb5a4f945 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2013-07-24 Paolo Carlini + + PR c++/57942 + * g++.dg/inherit/pr57942.C: New. + 2013-07-23 Michael Meissner * gcc.target/powerpc/bool2.h: New file, test the code generation diff --git a/gcc/testsuite/g++.dg/inherit/pr57942.C b/gcc/testsuite/g++.dg/inherit/pr57942.C new file mode 100644 index 00000000000..580e9ecd242 --- /dev/null +++ b/gcc/testsuite/g++.dg/inherit/pr57942.C @@ -0,0 +1,9 @@ +// PR c++/57942 + +template struct S { typename T::error type; }; +struct X {}; +void f(S*); +void f(...); +void g() { f((X*)0); } +struct Y; +void h() { f((Y*)0); } -- 2.11.4.GIT