[C++ Patch] Fix __is_base_of vs incomplete types

Paolo Carlini paolo.carlini@oracle.com
Fri Jan 3 23:28:00 GMT 2014


... something like the attached appears to work. Not sure at the moment 
if it could be simplified.

Thanks,
Paolo.

////////////////////
-------------- next part --------------
Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h	(revision 206318)
+++ cp/cp-tree.h	(working copy)
@@ -1324,7 +1324,12 @@ enum languages { lang_c, lang_cplusplus, lang_java
 /* Nonzero iff TYPE is derived from PARENT. Ignores accessibility and
    ambiguity issues.  */
 #define DERIVED_FROM_P(PARENT, TYPE) \
-  (lookup_base ((TYPE), (PARENT), ba_any, NULL, tf_none) != NULL_TREE)
+  (((TYPE) && (!TYPE_P (TYPE)						\
+	       || TYPE_BINFO (complete_type			        \
+			      (TYPE_MAIN_VARIANT (TYPE)))))		\
+   ? lookup_base ((TYPE), (PARENT), ba_any, NULL, tf_none) != NULL_TREE \
+   : ((TYPE) && NON_UNION_CLASS_TYPE_P (TYPE)				\
+      && same_type_ignoring_top_level_qualifiers_p ((PARENT), (TYPE))))
 
 /* Gives the visibility specification for a class type.  */
 #define CLASSTYPE_VISIBILITY(TYPE)		\
Index: cp/search.c
===================================================================
--- cp/search.c	(revision 206318)
+++ cp/search.c	(working copy)
@@ -177,8 +177,9 @@ accessible_base_p (tree t, tree base, bool conside
    discovered.
 
    If the base is inaccessible, or ambiguous, then error_mark_node is
-   returned.  If the tf_error bit of COMPLAIN is not set, no error
-   is issued.  */
+   returned.  If the tf_error bit of COMPLAIN is not set, no error is
+   issued.  If T cannot be completed, then NULL_TREE is returned even
+   if BASE is the same type.  */
 
 tree
 lookup_base (tree t, tree base, base_access access,
Index: testsuite/g++.dg/ext/is_base_of_incomplete-2.C
===================================================================
--- testsuite/g++.dg/ext/is_base_of_incomplete-2.C	(revision 0)
+++ testsuite/g++.dg/ext/is_base_of_incomplete-2.C	(working copy)
@@ -0,0 +1,5 @@
+struct T;
+
+int check1[__is_base_of(T, T) ? 1 : -1];
+int check2[__is_base_of(T, const T) ? 1 : -1];
+int check3[__is_base_of(volatile T, T) ? 1 : -1];


More information about the Gcc-patches mailing list