diff mbox

[C++] Fix __is_base_of vs incomplete types

Message ID 52C6F365.4040700@oracle.com
State New
Headers show

Commit Message

Paolo Carlini Jan. 3, 2014, 5:29 p.m. UTC
Hi,

On 01/02/2014 10:46 PM, Jason Merrill wrote:
> On 12/27/2013 07:02 AM, Paolo Carlini wrote:
>> the same arguments. Conservatively but still more neatly than my first
>> try, we could maybe use same_type_ignoring_top_level_qualifiers_p in the
>> definition of the DERIVED_FROM_P macro?
>
> Sure, let's do that.  And add something about incomplete types to the 
> pre-function comment for lookup_base.
Great. Thus I successfully tested on x86_64-linux the below.

Thanks,
Paolo.

////////////////////////
/cp
2014-01-03  Paolo Carlini  <paolo.carlini@oracle.com>

	* cp-tree.h (DERIVED_FROM_P): True when PARENT and TYPE are the same
	class-type (even if incomplete).
	* search.c (lookup_base): Extend comment.

/testsuite
2014-01-03  Paolo Carlini  <paolo.carlini@oracle.com>

	* g++.dg/ext/is_base_of_incomplete-2.C: New.

Comments

Jason Merrill Jan. 3, 2014, 6:47 p.m. UTC | #1
On 01/03/2014 12:29 PM, Paolo Carlini wrote:
> -  (lookup_base ((TYPE), (PARENT), ba_any, NULL, tf_none) != NULL_TREE)
> +  (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))))

Let's only check one or the other, depending on whether TYPE is incomplete.

> +   issued.  If the base in incomplete, then NULL_TREE is returned.  */

"If T is incomplete"

Jason
Jason Merrill Jan. 3, 2014, 6:47 p.m. UTC | #2
On 01/03/2014 01:47 PM, Jason Merrill wrote:
>> +   issued.  If the base in incomplete, then NULL_TREE is returned.  */
>
> "If T is incomplete"

"...even if BASE is the same type."

Jason
Paolo Carlini Jan. 3, 2014, 10:50 p.m. UTC | #3
Hi,

On 01/03/2014 07:47 PM, Jason Merrill wrote:
> On 01/03/2014 12:29 PM, Paolo Carlini wrote:
>> -  (lookup_base ((TYPE), (PARENT), ba_any, NULL, tf_none) != NULL_TREE)
>> +  (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))))
> Let's only check one or the other, depending on whether TYPE is 
> incomplete.
The dispatching seems tricky, though, because lookup_base has:

    if (!TYPE_P (t))
     {
       t_binfo = t;
       t = BINFO_TYPE (t);
     }
   else
     {
       t = complete_type (TYPE_MAIN_VARIANT (t));
       t_binfo = TYPE_BINFO (t);
     }

thus TYPE_P (t) isn't necessarily true and, more importantly, otherwise 
the function actively tries to complete the type. Do you think it can work?

Thanks,
Paolo.

PS: sorry about the sloppy comment in my last try ;)
diff mbox

Patch

Index: cp/cp-tree.h
===================================================================
--- cp/cp-tree.h	(revision 206313)
+++ cp/cp-tree.h	(working copy)
@@ -1324,7 +1324,9 @@  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)
+  (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 206313)
+++ cp/search.c	(working copy)
@@ -177,8 +177,8 @@  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 the base in incomplete, then NULL_TREE is returned.  */
 
 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];