FreeBSD/contrib/gcc/cp/typeck.c
/* Return the composite pointer type (see [expr.rel]) for T1 and T2.
   ARG1 and ARG2 are the values with those types.  The LOCATION is a
   string describing the current location, in case an error occurs.

   This routine also implements the computation of a common type for
   pointers-to-members as per [expr.eq].  */
Return the composite pointer type  for T1 and T2.
ARG1 and ARG2 are the values with those types.  The LOCATION is a
string describing the current location, in case an error occurs.

This routine also implements the computation of a common type for
pointers-to-members as per [expr.eq].
Return the composite pointer type for T1 and T2 . ARG1 and ARG2 are the values with those types . The LOCATION is a string describing the current location in case an error occurs . This routine also implements the computation of a common type for pointers - to - members as per [ expr . eq ] .
tree
composite_pointer_type (tree t1, tree t2, tree arg1, tree arg2,
			const char* location)
{
  tree class1;
  tree class2;
  if (null_ptr_cst_p (arg1))
    return t2;
  if (null_ptr_cst_p (arg2))
    return t1;
  if (TREE_CODE (t2) == POINTER_TYPE && VOID_TYPE_P (TREE_TYPE (t2)))
    {
      tree t;
      t = t1;
      t1 = t2;
      t2 = t;
    }
  if (TREE_CODE (t1) == POINTER_TYPE && VOID_TYPE_P (TREE_TYPE (t1)))
    {
      tree attributes;
      tree result_type;
      if (pedantic && TYPE_PTRFN_P (t2))
	pedwarn ("ISO C++ forbids %s between pointer of type %<void *%> "
		 "and pointer-to-function", location);
      result_type
	= cp_build_qualified_type (void_type_node,
				   (cp_type_quals (TREE_TYPE (t1))
				    | cp_type_quals (TREE_TYPE (t2))));
      result_type = build_pointer_type (result_type);
      attributes = (*targetm.merge_type_attributes) (t1, t2);
      return build_type_attribute_variant (result_type, attributes);
    }
  if (c_dialect_objc () && TREE_CODE (t1) == POINTER_TYPE
      && TREE_CODE (t2) == POINTER_TYPE)
    {
      if (objc_have_common_type (t1, t2, -3, NULL_TREE, location))
	return objc_common_type (t1, t2);
    }
  if (TREE_CODE (t1) == POINTER_TYPE && TREE_CODE (t2) == POINTER_TYPE
      && CLASS_TYPE_P (TREE_TYPE (t1))
      && CLASS_TYPE_P (TREE_TYPE (t2))
      && !same_type_ignoring_top_level_qualifiers_p (TREE_TYPE (t1),
						     TREE_TYPE (t2)))
    {
      class1 = TREE_TYPE (t1);
      class2 = TREE_TYPE (t2);
      if (DERIVED_FROM_P (class1, class2))
	t2 = (build_pointer_type
	      (cp_build_qualified_type (class1, TYPE_QUALS (class2))));
      else if (DERIVED_FROM_P (class2, class1))
	t1 = (build_pointer_type
	      (cp_build_qualified_type (class2, TYPE_QUALS (class1))));
      else
	{
	  error ("%s between distinct pointer types %qT and %qT "
		 "lacks a cast", location, t1, t2);
	  return error_mark_node;
	}
    }
  else if (TYPE_PTR_TO_MEMBER_P (t1)
	   && !same_type_p (TYPE_PTRMEM_CLASS_TYPE (t1),
			    TYPE_PTRMEM_CLASS_TYPE (t2)))
    {
      class1 = TYPE_PTRMEM_CLASS_TYPE (t1);
      class2 = TYPE_PTRMEM_CLASS_TYPE (t2);
      if (DERIVED_FROM_P (class1, class2))
	t1 = build_ptrmem_type (class2, TYPE_PTRMEM_POINTED_TO_TYPE (t1));
      else if (DERIVED_FROM_P (class2, class1))
	t2 = build_ptrmem_type (class1, TYPE_PTRMEM_POINTED_TO_TYPE (t2));
      else
	{
	  error ("%s between distinct pointer-to-member types %qT and %qT "
		 "lacks a cast", location, t1, t2);
	  return error_mark_node;
	}
    }
  else if (TREE_CODE (t1) != TREE_CODE (t2))
    {
      error ("%s between distinct pointer types %qT and %qT "
	     "lacks a cast", location, t1, t2);
      return error_mark_node;
    }
  return composite_pointer_type_r (t1, t2, location);
}
tree composite_pointer_type ( tree t1 , tree t2 , tree arg1 , tree arg2 , const char * location ) { tree class1 ; tree class2 ; if ( null_ptr_cst_p ( arg1 ) ) return t2 ; if ( null_ptr_cst_p ( arg2 ) ) return t1 ; if ( TREE_CODE ( t2 ) == POINTER_TYPE && VOID_TYPE_P ( TREE_TYPE ( t2 ) ) ) { tree t ; t = t1 ; t1 = t2 ; t2 = t ; } if ( TREE_CODE ( t1 ) == POINTER_TYPE && VOID_TYPE_P ( TREE_TYPE ( t1 ) ) ) { tree attributes ; tree result_type ; if ( pedantic && TYPE_PTRFN_P ( t2 ) ) pedwarn ( " " " " , location ) ; result_type = cp_build_qualified_type ( void_type_node , ( cp_type_quals ( TREE_TYPE ( t1 ) ) | cp_type_quals ( TREE_TYPE ( t2 ) ) ) ) ; result_type = build_pointer_type ( result_type ) ; attributes = ( * targetm . merge_type_attributes ) ( t1 , t2 ) ; return build_type_attribute_variant ( result_type , attributes ) ; } if ( c_dialect_objc ( ) && TREE_CODE ( t1 ) == POINTER_TYPE && TREE_CODE ( t2 ) == POINTER_TYPE ) { if ( objc_have_common_type ( t1 , t2 , -3 , NULL_TREE , location ) ) return objc_common_type ( t1 , t2 ) ; } if ( TREE_CODE ( t1 ) == POINTER_TYPE && TREE_CODE ( t2 ) == POINTER_TYPE && CLASS_TYPE_P ( TREE_TYPE ( t1 ) ) && CLASS_TYPE_P ( TREE_TYPE ( t2 ) ) && ! same_type_ignoring_top_level_qualifiers_p ( TREE_TYPE ( t1 ) , TREE_TYPE ( t2 ) ) ) { class1 = TREE_TYPE ( t1 ) ; class2 = TREE_TYPE ( t2 ) ; if ( DERIVED_FROM_P ( class1 , class2 ) ) t2 = ( build_pointer_type ( cp_build_qualified_type ( class1 , TYPE_QUALS ( class2 ) ) ) ) ; else if ( DERIVED_FROM_P ( class2 , class1 ) ) t1 = ( build_pointer_type ( cp_build_qualified_type ( class2 , TYPE_QUALS ( class1 ) ) ) ) ; else { error ( " " " " , location , t1 , t2 ) ; return error_mark_node ; } } else if ( TYPE_PTR_TO_MEMBER_P ( t1 ) && ! same_type_p ( TYPE_PTRMEM_CLASS_TYPE ( t1 ) , TYPE_PTRMEM_CLASS_TYPE ( t2 ) ) ) { class1 = TYPE_PTRMEM_CLASS_TYPE ( t1 ) ; class2 = TYPE_PTRMEM_CLASS_TYPE ( t2 ) ; if ( DERIVED_FROM_P ( class1 , class2 ) ) t1 = build_ptrmem_type ( class2 , TYPE_PTRMEM_POINTED_TO_TYPE ( t1 ) ) ; else if ( DERIVED_FROM_P ( class2 , class1 ) ) t2 = build_ptrmem_type ( class1 , TYPE_PTRMEM_POINTED_TO_TYPE ( t2 ) ) ; else { error ( " " " " , location , t1 , t2 ) ; return error_mark_node ; } } else if ( TREE_CODE ( t1 ) != TREE_CODE ( t2 ) ) { error ( " " " " , location , t1 , t2 ) ; return error_mark_node ; } return composite_pointer_type_r ( t1 , t2 , location ) ; }
Return the composite pointer type (see [expr.rel]) for T1 and T2.
Return the composite pointer type ( see [ expr . rel ] ) for T1 and T2 .
/* [expr.rel]

     If one operand is a null pointer constant, the composite pointer
     type is the type of the other operand.  */ /* We have:

       [expr.rel]

       If one of the operands has type "pointer to cv1 void*", then
       the other has type "pointer to cv2T", and the composite pointer
       type is "pointer to cv12 void", where cv12 is the union of cv1
       and cv2.

    If either type is a pointer to void, make sure it is T1.  */ /* Now, if T1 is a pointer to void, merge the qualifiers.  */ /* Merge the attributes.  */ /* APPLE LOCAL radar 4229905 - radar 6231433 */ /* APPLE LOCAL 4154928 */ /* [expr.eq] permits the application of a pointer conversion to
     bring the pointers to a common type.  */ /* [expr.eq] permits the application of a pointer-to-member
     conversion to change the class type of one of the types.  */ /* APPLE LOCAL begin blocks 6065211 */ /* APPLE LOCAL end blocks 6065211 */