This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

C++ PATCH to conditional_conversion for c++/5388


Yet Another ?: patch.

In 5388, we have a derived class which has a constructor taking a reference
to the base class, and a ?: expression with options of each class.
Previously we were considering the user-defined conversion from base to
derived, but the standard says that we only look for arbitrary conversions
if the two classes involved are not related by inheritance.  Fixed thus.

While I was at it, I tweaked the DERIVED_FROM_P family of macros to have
boolean values instead of returning binfos.

Tested i686-pc-linux-gnu, applied to 3.3 and trunk.  Test in
g++.dg/conversion/cond5.C.

2003-05-15  Jason Merrill  <jason@redhat.com>

	PR c++/5388
	* call.c (conditional_conversion): Don't consider implicit
	conversions if T2 is a base of T1. 
	* cp-tree.h (DERIVED_FROM_P, UNIQUELY_DERIVED_FROM_P): Make boolean.
	(ACCESSIBLY_UNIQUELY_DERIVED_P, PUBLICLY_UNIQUELY_DERIVED_P): Likewise.

*** cp-tree.h.~1~	2003-05-15 16:44:09.000000000 -0400
--- cp-tree.h	2003-05-15 14:58:21.000000000 -0400
*************** enum languages { lang_c, lang_cplusplus,
*** 993,1010 ****
  /* 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)
  /* Nonzero iff TYPE is uniquely derived from PARENT. Ignores
     accessibility.  */
  #define UNIQUELY_DERIVED_FROM_P(PARENT, TYPE) \
!   lookup_base ((TYPE), (PARENT), ba_ignore | ba_quiet, NULL)
  /* Nonzero iff TYPE is accessible in the current scope and uniquely
     derived from PARENT.  */
  #define ACCESSIBLY_UNIQUELY_DERIVED_P(PARENT, TYPE) \
!   lookup_base ((TYPE), (PARENT), ba_check | ba_quiet, NULL)
  /* Nonzero iff TYPE is publicly & uniquely derived from PARENT.  */
  #define PUBLICLY_UNIQUELY_DERIVED_P(PARENT, TYPE) \
!   lookup_base ((TYPE), (PARENT),  ba_not_special | ba_quiet, NULL)
  
  /* This is a few header flags for 'struct lang_type'.  Actually,
     all but the first are used only for lang_type_class; they
--- 993,1011 ----
  /* 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) != NULL_TREE)
  /* Nonzero iff TYPE is uniquely derived from PARENT. Ignores
     accessibility.  */
  #define UNIQUELY_DERIVED_FROM_P(PARENT, TYPE) \
!   (lookup_base ((TYPE), (PARENT), ba_ignore | ba_quiet, NULL) != NULL_TREE)
  /* Nonzero iff TYPE is accessible in the current scope and uniquely
     derived from PARENT.  */
  #define ACCESSIBLY_UNIQUELY_DERIVED_P(PARENT, TYPE) \
!   (lookup_base ((TYPE), (PARENT), ba_check | ba_quiet, NULL) != NULL_TREE)
  /* Nonzero iff TYPE is publicly & uniquely derived from PARENT.  */
  #define PUBLICLY_UNIQUELY_DERIVED_P(PARENT, TYPE) \
!   (lookup_base ((TYPE), (PARENT),  ba_not_special | ba_quiet, NULL) \
!    != NULL_TREE)
  
  /* This is a few header flags for 'struct lang_type'.  Actually,
     all but the first are used only for lang_type_class; they
*** call.c.~1~	2003-05-15 16:44:09.000000000 -0400
--- call.c	2003-05-15 14:31:30.000000000 -0400
*************** conditional_conversion (tree e1, tree e2
*** 3161,3166 ****
--- 3161,3167 ----
    tree t1 = non_reference (TREE_TYPE (e1));
    tree t2 = non_reference (TREE_TYPE (e2));
    tree conv;
+   bool good_base;
  
    /* [expr.cond]
  
*************** conditional_conversion (tree e1, tree e2
*** 3192,3201 ****
       FIXME we can't express an rvalue that refers to the original object;
       we have to create a new one.  */
    if (CLASS_TYPE_P (t1) && CLASS_TYPE_P (t2)
!       && same_or_base_type_p (TYPE_MAIN_VARIANT (t2), 
! 			      TYPE_MAIN_VARIANT (t1)))
      {
!       if (at_least_as_qualified_p (t2, t1))
  	{
  	  conv = build1 (IDENTITY_CONV, t1, e1);
  	  if (!same_type_p (TYPE_MAIN_VARIANT (t1), 
--- 3193,3201 ----
       FIXME we can't express an rvalue that refers to the original object;
       we have to create a new one.  */
    if (CLASS_TYPE_P (t1) && CLASS_TYPE_P (t2)
!       && ((good_base = DERIVED_FROM_P (t2, t1)) || DERIVED_FROM_P (t1, t2)))
      {
!       if (good_base && at_least_as_qualified_p (t2, t1))
  	{
  	  conv = build1 (IDENTITY_CONV, t1, e1);
  	  if (!same_type_p (TYPE_MAIN_VARIANT (t1), 
*************** conditional_conversion (tree e1, tree e2
*** 3211,3223 ****
        else
  	return NULL_TREE;
      }
  
!   /* [expr.cond]
! 
!      E1 can be converted to match E2 if E1 can be implicitly converted
!      to the type that expression E2 would have if E2 were converted to
!      an rvalue (or the type it has, if E2 is an rvalue).  */
!   return implicit_conversion (t2, t1, e1, LOOKUP_NORMAL);
  }
  
  /* Implement [expr.cond].  ARG1, ARG2, and ARG3 are the three
--- 3211,3223 ----
        else
  	return NULL_TREE;
      }
+   else
+     /* [expr.cond]
  
!        Otherwise: E1 can be converted to match E2 if E1 can be implicitly
!        converted to the type that expression E2 would have if E2 were
!        converted to an rvalue (or the type it has, if E2 is an rvalue).  */
!     return implicit_conversion (t2, t1, e1, LOOKUP_NORMAL);
  }
  
  /* Implement [expr.cond].  ARG1, ARG2, and ARG3 are the three

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]