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]

Re: [C++ PATCH]: make cp_tree_equal unequivocal


Mark Mitchell wrote:

The comment at the top of cp_tree_equal should change, right?  (It no
longer is ever supposed to return -1.)
yes. I then wandered into comptypes, and this patch supercedes the previous
one. I suspect I can go through some callers of comptypes (duplicate_decls
et al), to boolify them

The RELAXED checking for enumerations and java types does not appear
to be used anywhere.

Does your change make sense for comptypes, which seems to be the only
places checking for a negative return value?  It looks to me like for
UNBOUND_CLASS_TEMPLATE comptypes would have always returned 0; as far as
I can see cp_tree_equal always returns -1 for IDENTIFIER_NODES.  (I'm
not sure that cp_tree_equal should even be *called* with an
IDENTIFIER_NODE; it really should get expressions, but that's another
issue...)
you get identifier nodes in SCOPE_REFs. Remember there is a test at the
top checking for node equality.

booted & tested on i686-pc-linux-gnu, ok?

nathan

--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
         The voices in my head said this was stupid too
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2003-06-18  Nathan Sidwell  <nathan@codesourcery.com>

	* cp-tree.h (COMPARE_RELAXED): Rename to ...
	(COMPARE_DERIVED): ... here. Adjust comment.
	(resolve_typename_type_in_current_instantiation): Remove.
	(cp_tree_equal, comptypes): Return a bool.
	* cvt.c (convert_to_reference): Adjust comptypes call.
	* pt.c (template_args_equal, unify,): Adjust cp_tree_equal call.
	(resolve_typename_type_in_current_instantiation): Remove.
	* tree.c (cp_tree_equal): Return bool. Cope with TEMPLATE_DECLs and
	IDENTIFIER_NODEs. Abort if undeciderable. Adjust recursive
	calls. Refactor code.
	* typeck.c (comp_array_types): Return bool. Lose callback.
	parameter. Adjust cp_tree_equal calls.
	(comptypes): Return bool. Adjust strict handling. Remove relaxed
	enumeration and java type handling. Deal with typename types here.
	Adjust recursive and cp_tree_equals calls. Adjust base and derived
	checking.
	(comp_target_types): Remove unreachable code. Adjust
	same_or_base_type_p calls.
	(ptr_reasonably_similar): Adjust base and derived check.
	
	* typeck.c (maybe_warn_about_returning_address_of_local): Remove
	unused calculation.
	(check_return_expr): Adjust error messages.
	* cp-tree.def (SCOPE_REF): Correct comment.

Index: cp/cp-tree.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.def,v
retrieving revision 1.73
diff -c -3 -p -r1.73 cp-tree.def
*** cp/cp-tree.def	7 Apr 2003 06:03:14 -0000	1.73
--- cp/cp-tree.def	18 Jun 2003 10:24:37 -0000
*************** DEFTREECODE (DELETE_EXPR, "dl_expr", 'e'
*** 62,69 ****
  DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", 'e', 2)
  
  /* Value is reference to particular overloaded class method.
!    Operand 0 is the class name (an IDENTIFIER_NODE);
!    operand 1 is the field (also an IDENTIFIER_NODE).
     The COMPLEXITY field holds the class level (usually 0).  */
  DEFTREECODE (SCOPE_REF, "scope_ref", 'r', 2)
  
--- 62,68 ----
  DEFTREECODE (VEC_DELETE_EXPR, "vec_dl_expr", 'e', 2)
  
  /* Value is reference to particular overloaded class method.
!    Operand 0 is the class, operand 1 is the field
     The COMPLEXITY field holds the class level (usually 0).  */
  DEFTREECODE (SCOPE_REF, "scope_ref", 'r', 2)
  
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.852
diff -c -3 -p -r1.852 cp-tree.h
*** cp/cp-tree.h	16 Jun 2003 13:15:35 -0000	1.852
--- cp/cp-tree.h	18 Jun 2003 10:24:50 -0000
*************** enum overload_flags { NO_SPECIAL = 0, DT
*** 3362,3376 ****
  #define COMPARE_STRICT        0 /* Just check if the types are the
  				   same.  */
  #define COMPARE_BASE          1 /* Check to see if the second type is
! 				   derived from the first, or if both
! 				   are pointers (or references) and
! 				   the types pointed to by the second
! 				   type is derived from the pointed to
! 				   by the first.  */
! #define COMPARE_RELAXED       2 /* Like COMPARE_DERIVED, but in
! 				   reverse.  Also treat enumeration
! 				   types as the same as integer types
! 				   of the same width.  */
  #define COMPARE_REDECLARATION 4 /* The comparsion is being done when
  				   another declaration of an existing
  				   entity is seen.  */
--- 3362,3370 ----
  #define COMPARE_STRICT        0 /* Just check if the types are the
  				   same.  */
  #define COMPARE_BASE          1 /* Check to see if the second type is
! 				   derived from the first.  */
! #define COMPARE_DERIVED       2 /* Like COMPARE_BASE, but in
! 				   reverse.  */
  #define COMPARE_REDECLARATION 4 /* The comparsion is being done when
  				   another declaration of an existing
  				   entity is seen.  */
*************** extern bool dependent_template_p        
*** 3977,3983 ****
  extern bool type_dependent_expression_p         (tree);
  extern bool value_dependent_expression_p        (tree);
  extern tree resolve_typename_type               (tree, bool);
- extern tree resolve_typename_type_in_current_instantiation (tree);
  extern tree template_for_substitution           (tree);
  
  /* in repo.c */
--- 3971,3976 ----
*************** extern tree error_type				(tree);
*** 4199,4205 ****
  extern tree build_zc_wrapper			(struct z_candidate *);
  extern int varargs_function_p			(tree);
  extern int really_overloaded_fn			(tree);
! extern int cp_tree_equal			(tree, tree);
  extern tree no_linkage_check			(tree);
  extern void debug_binfo				(tree);
  extern tree build_dummy_object			(tree);
--- 4192,4198 ----
  extern tree build_zc_wrapper			(struct z_candidate *);
  extern int varargs_function_p			(tree);
  extern int really_overloaded_fn			(tree);
! extern bool cp_tree_equal			(tree, tree);
  extern tree no_linkage_check			(tree);
  extern void debug_binfo				(tree);
  extern tree build_dummy_object			(tree);
*************** extern int type_unknown_p			(tree);
*** 4242,4248 ****
  extern tree commonparms				(tree, tree);
  extern tree original_type			(tree);
  extern int comp_except_specs			(tree, tree, int);
! extern int comptypes				(tree, tree, int);
  extern int comp_target_types			(tree, tree, int);
  extern int compparms				(tree, tree);
  extern int comp_cv_qualification                (tree, tree);
--- 4235,4241 ----
  extern tree commonparms				(tree, tree);
  extern tree original_type			(tree);
  extern int comp_except_specs			(tree, tree, int);
! extern bool comptypes				(tree, tree, int);
  extern int comp_target_types			(tree, tree, int);
  extern int compparms				(tree, tree);
  extern int comp_cv_qualification                (tree, tree);
Index: cp/cvt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cvt.c,v
retrieving revision 1.136
diff -c -3 -p -r1.136 cvt.c
*** cp/cvt.c	3 Apr 2003 20:07:56 -0000	1.136
--- cp/cvt.c	18 Jun 2003 10:24:52 -0000
*************** convert_to_reference (tree reftype, tree
*** 507,516 ****
        /* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they
           meant.  */
        if (TREE_CODE (intype) == POINTER_TYPE
! 	  && (comptypes (TREE_TYPE (intype), type, 
! 			 COMPARE_BASE | COMPARE_RELAXED )))
  	warning ("casting `%T' to `%T' does not dereference pointer",
! 		    intype, reftype);
  	  
        rval = build_unary_op (ADDR_EXPR, expr, 0);
        if (rval != error_mark_node)
--- 507,516 ----
        /* B* bp; A& ar = (A&)bp; is valid, but it's probably not what they
           meant.  */
        if (TREE_CODE (intype) == POINTER_TYPE
! 	  && (comptypes (TREE_TYPE (intype), type,
! 			 COMPARE_BASE | COMPARE_DERIVED)))
  	warning ("casting `%T' to `%T' does not dereference pointer",
! 		 intype, reftype);
  	  
        rval = build_unary_op (ADDR_EXPR, expr, 0);
        if (rval != error_mark_node)
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.700
diff -c -3 -p -r1.700 pt.c
*** cp/pt.c	16 Jun 2003 21:41:08 -0000	1.700
--- cp/pt.c	18 Jun 2003 10:25:53 -0000
*************** template_args_equal (ot, nt)
*** 3811,3817 ****
    else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot))
      return 0;
    else
!     return (cp_tree_equal (ot, nt) > 0);
  }
  
  /* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets
--- 3811,3817 ----
    else if (TREE_CODE (ot) == TREE_VEC || TYPE_P (ot))
      return 0;
    else
!     return cp_tree_equal (ot, nt);
  }
  
  /* Returns 1 iff the OLDARGS and NEWARGS are in fact identical sets
*************** unify (tparms, targs, parm, arg, strict)
*** 9638,9659 ****
  	  != template_decl_level (tparm))
  	/* The PARM is not one we're trying to unify.  Just check
  	   to see if it matches ARG.  */
! 	return (TREE_CODE (arg) == TREE_CODE (parm)
! 		&& cp_tree_equal (parm, arg) > 0) ? 0 : 1;
  
        idx = TEMPLATE_PARM_IDX (parm);
        targ = TREE_VEC_ELT (targs, idx);
  
        if (targ)
! 	{
! 	  int i = (cp_tree_equal (targ, arg) > 0);
! 	  if (i == 1)
! 	    return 0;
! 	  else if (i == 0)
! 	    return 1;
! 	  else
! 	    abort ();
! 	}
  
        /* [temp.deduct.type] If, in the declaration of a function template
  	 with a non-type template-parameter, the non-type
--- 9638,9651 ----
  	  != template_decl_level (tparm))
  	/* The PARM is not one we're trying to unify.  Just check
  	   to see if it matches ARG.  */
! 	return !(TREE_CODE (arg) == TREE_CODE (parm)
! 		 && cp_tree_equal (parm, arg));
  
        idx = TEMPLATE_PARM_IDX (parm);
        targ = TREE_VEC_ELT (targs, idx);
  
        if (targ)
! 	return !cp_tree_equal (targ, arg);
  
        /* [temp.deduct.type] If, in the declaration of a function template
  	 with a non-type template-parameter, the non-type
*************** resolve_typename_type (tree type, bool o
*** 11796,11810 ****
    pop_scope (scope);
  
    return type;
- }
- 
- tree
- resolve_typename_type_in_current_instantiation (tree type)
- {
-   tree t;
- 
-   t = resolve_typename_type (type, /*only_current_p=*/true);
-   return (t != error_mark_node) ? t : type;
  }
  
  #include "gt-cp-pt.h"
--- 11788,11793 ----
Index: cp/tree.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/tree.c,v
retrieving revision 1.330
diff -c -3 -p -r1.330 tree.c
*** cp/tree.c	16 Jun 2003 21:41:09 -0000	1.330
--- cp/tree.c	18 Jun 2003 10:25:57 -0000
*************** decl_namespace_context (tree decl)
*** 1552,1589 ****
  }
  
  /* Return truthvalue of whether T1 is the same tree structure as T2.
!    Return 1 if they are the same.
!    Return 0 if they are understandably different.
!    Return -1 if either contains tree structure not understood by
!    this function.  */
  
! int
  cp_tree_equal (tree t1, tree t2)
  {
    register enum tree_code code1, code2;
-   int cmp;
  
    if (t1 == t2)
!     return 1;
!   if (t1 == 0 || t2 == 0)
!     return 0;
! 
!   code1 = TREE_CODE (t1);
!   code2 = TREE_CODE (t2);
! 
!   if (code1 == NOP_EXPR || code1 == CONVERT_EXPR || code1 == NON_LVALUE_EXPR)
!     {
!       if (code2 == NOP_EXPR || code2 == CONVERT_EXPR || code2 == NON_LVALUE_EXPR)
! 	return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
!       else
! 	return cp_tree_equal (TREE_OPERAND (t1, 0), t2);
!     }
!   else if (code2 == NOP_EXPR || code2 == CONVERT_EXPR
! 	   || code2 == NON_LVALUE_EXPR)
!     return cp_tree_equal (t1, TREE_OPERAND (t2, 0));
  
    if (code1 != code2)
!     return 0;
  
    switch (code1)
      {
--- 1552,1586 ----
  }
  
  /* Return truthvalue of whether T1 is the same tree structure as T2.
!    Return 1 if they are the same. Return 0 if they are different.  */
  
! bool
  cp_tree_equal (tree t1, tree t2)
  {
    register enum tree_code code1, code2;
  
    if (t1 == t2)
!     return true;
!   if (!t1 || !t2)
!     return false;
! 
!   for (code1 = TREE_CODE (t1);
!        code1 == NOP_EXPR || code1 == CONVERT_EXPR
! 	 || code1 == NON_LVALUE_EXPR;
!        code1 = TREE_CODE (t1))
!     t1 = TREE_OPERAND (t1, 0);
!   for (code2 = TREE_CODE (t2);
!        code2 == NOP_EXPR || code2 == CONVERT_EXPR
! 	 || code1 == NON_LVALUE_EXPR;
!        code2 = TREE_CODE (t2))
!     t2 = TREE_OPERAND (t2, 0);
  
+   /* They might have become equal now.  */
+   if (t1 == t2)
+     return true;
+   
    if (code1 != code2)
!     return false;
  
    switch (code1)
      {
*************** cp_tree_equal (tree t1, tree t2)
*** 1597,1603 ****
      case STRING_CST:
        return TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
  	&& !memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
! 		  TREE_STRING_LENGTH (t1));
  
      case CONSTRUCTOR:
        /* We need to do this when determining whether or not two
--- 1594,1600 ----
      case STRING_CST:
        return TREE_STRING_LENGTH (t1) == TREE_STRING_LENGTH (t2)
  	&& !memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
! 		    TREE_STRING_LENGTH (t1));
  
      case CONSTRUCTOR:
        /* We need to do this when determining whether or not two
*************** cp_tree_equal (tree t1, tree t2)
*** 1606,1666 ****
        if (!(same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
  	    /* The first operand is RTL.  */
  	    && TREE_OPERAND (t1, 0) == TREE_OPERAND (t2, 0)))
! 	return 0;
        return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
  
      case TREE_LIST:
!       cmp = cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2));
!       if (cmp <= 0)
! 	return cmp;
!       cmp = cp_tree_equal (TREE_VALUE (t1), TREE_VALUE (t2));
!       if (cmp <= 0)
! 	return cmp;
        return cp_tree_equal (TREE_CHAIN (t1), TREE_CHAIN (t2));
  
      case SAVE_EXPR:
        return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
  
      case CALL_EXPR:
!       cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
!       if (cmp <= 0)
! 	return cmp;
!       return simple_cst_list_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
! 
!     case TARGET_EXPR:
!       /* Special case: if either target is an unallocated VAR_DECL,
! 	 it means that it's going to be unified with whatever the
! 	 TARGET_EXPR is really supposed to initialize, so treat it
! 	 as being equivalent to anything.  */
!       if ((TREE_CODE (TREE_OPERAND (t1, 0)) == VAR_DECL
! 	   && DECL_NAME (TREE_OPERAND (t1, 0)) == NULL_TREE
! 	   && !DECL_RTL_SET_P (TREE_OPERAND (t1, 0)))
! 	  || (TREE_CODE (TREE_OPERAND (t2, 0)) == VAR_DECL
! 	      && DECL_NAME (TREE_OPERAND (t2, 0)) == NULL_TREE
! 	      && !DECL_RTL_SET_P (TREE_OPERAND (t2, 0))))
! 	cmp = 1;
!       else
! 	cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
!       if (cmp <= 0)
! 	return cmp;
        return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
  
      case WITH_CLEANUP_EXPR:
!       cmp = cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
!       if (cmp <= 0)
! 	return cmp;
        return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t1, 1));
  
      case COMPONENT_REF:
!       if (TREE_OPERAND (t1, 1) == TREE_OPERAND (t2, 1))
! 	return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
!       return 0;
  
      case VAR_DECL:
      case PARM_DECL:
      case CONST_DECL:
      case FUNCTION_DECL:
!       return 0;
  
      case TEMPLATE_PARM_INDEX:
        return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
--- 1603,1664 ----
        if (!(same_type_p (TREE_TYPE (t1), TREE_TYPE (t2))
  	    /* The first operand is RTL.  */
  	    && TREE_OPERAND (t1, 0) == TREE_OPERAND (t2, 0)))
! 	return false;
        return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
  
      case TREE_LIST:
!       if (!cp_tree_equal (TREE_PURPOSE (t1), TREE_PURPOSE (t2)))
! 	return false;
!       if (!cp_tree_equal (TREE_VALUE (t1), TREE_VALUE (t2)))
! 	return false;
        return cp_tree_equal (TREE_CHAIN (t1), TREE_CHAIN (t2));
  
      case SAVE_EXPR:
        return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
  
      case CALL_EXPR:
!       if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
! 	return false;
        return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
  
+     case TARGET_EXPR:
+       {
+ 	tree o1 = TREE_OPERAND (t1, 0);
+ 	tree o2 = TREE_OPERAND (t2, 0);
+ 	
+ 	/* Special case: if either target is an unallocated VAR_DECL,
+ 	   it means that it's going to be unified with whatever the
+ 	   TARGET_EXPR is really supposed to initialize, so treat it
+ 	   as being equivalent to anything.  */
+ 	if (TREE_CODE (o1) == VAR_DECL && DECL_NAME (o1) == NULL_TREE
+ 	    && !DECL_RTL_SET_P (o1))
+ 	  /*Nop*/;
+ 	else if (TREE_CODE (o2) == VAR_DECL && DECL_NAME (o2) == NULL_TREE
+ 		 && !DECL_RTL_SET_P (o2))
+ 	  /*Nop*/;
+ 	else if (!cp_tree_equal (o1, o2))
+ 	  return false;
+       
+ 	return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t2, 1));
+       }
+       
      case WITH_CLEANUP_EXPR:
!       if (!cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0)))
! 	return false;
        return cp_tree_equal (TREE_OPERAND (t1, 1), TREE_OPERAND (t1, 1));
  
      case COMPONENT_REF:
!       if (TREE_OPERAND (t1, 1) != TREE_OPERAND (t2, 1))
! 	return false;
!       return cp_tree_equal (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
  
      case VAR_DECL:
      case PARM_DECL:
      case CONST_DECL:
      case FUNCTION_DECL:
!     case TEMPLATE_DECL:
!     case IDENTIFIER_NODE:
!       return false;
  
      case TEMPLATE_PARM_INDEX:
        return (TEMPLATE_PARM_IDX (t1) == TEMPLATE_PARM_IDX (t2)
*************** cp_tree_equal (tree t1, tree t2)
*** 1670,1686 ****
  
      case SIZEOF_EXPR:
      case ALIGNOF_EXPR:
!       if (TREE_CODE (TREE_OPERAND (t1, 0)) != TREE_CODE (TREE_OPERAND (t2, 0)))
! 	return 0;
!       if (TYPE_P (TREE_OPERAND (t1, 0)))
! 	return same_type_p (TREE_OPERAND (t1, 0), TREE_OPERAND (t2, 0));
!       break;
! 
      case PTRMEM_CST:
        /* Two pointer-to-members are the same if they point to the same
  	 field or function in the same class.  */
!       return (PTRMEM_CST_MEMBER (t1) == PTRMEM_CST_MEMBER (t2)
! 	      && same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2)));
  
      default:
        break;
--- 1668,1692 ----
  
      case SIZEOF_EXPR:
      case ALIGNOF_EXPR:
!       {
! 	tree o1 = TREE_OPERAND (t1, 0);
! 	tree o2 = TREE_OPERAND (t2, 0);
! 	
! 	if (TREE_CODE (o1) != TREE_CODE (o2))
! 	  return false;
! 	if (TYPE_P (o1))
! 	  return same_type_p (o1, o2);
! 	else
! 	  return cp_tree_equal (o1, o2);
!       }
!       
      case PTRMEM_CST:
        /* Two pointer-to-members are the same if they point to the same
  	 field or function in the same class.  */
!       if (PTRMEM_CST_MEMBER (t1) != PTRMEM_CST_MEMBER (t2))
! 	return false;
! 
!       return same_type_p (PTRMEM_CST_CLASS (t1), PTRMEM_CST_CLASS (t2));
  
      default:
        break;
*************** cp_tree_equal (tree t1, tree t2)
*** 1697,1717 ****
        {
  	int i;
  	
- 	cmp = 1;
  	for (i = 0; i < TREE_CODE_LENGTH (code1); ++i)
! 	  {
! 	    cmp = cp_tree_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i));
! 	    if (cmp <= 0)
! 	      return cmp;
! 	  }
! 	return cmp;
        }
      
!       case 't':
! 	return same_type_p (t1, t2) ? 1 : 0;
      }
  
!   return -1;
  }
  
  /* Build a wrapper around a 'struct z_candidate' so we can use it as a
--- 1703,1721 ----
        {
  	int i;
  	
  	for (i = 0; i < TREE_CODE_LENGTH (code1); ++i)
! 	  if (!cp_tree_equal (TREE_OPERAND (t1, i), TREE_OPERAND (t2, i)))
! 	    return false;
! 	
! 	return true;
        }
      
!     case 't':
!       return same_type_p (t1, t2);
      }
  
!   my_friendly_assert (0, 20030617);
!   return false;
  }
  
  /* Build a wrapper around a 'struct z_candidate' so we can use it as a
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.464
diff -c -3 -p -r1.464 typeck.c
*** cp/typeck.c	12 Jun 2003 17:21:39 -0000	1.464
--- cp/typeck.c	18 Jun 2003 10:26:12 -0000
*************** static int comp_ptr_ttypes_real PARAMS (
*** 54,61 ****
  static int comp_ptr_ttypes_const PARAMS ((tree, tree));
  static int comp_ptr_ttypes_reinterpret PARAMS ((tree, tree));
  static int comp_except_types PARAMS ((tree, tree, int));
! static int comp_array_types PARAMS ((int (*) (tree, tree, int), tree,
! 				   tree, int));
  static tree common_base_type PARAMS ((tree, tree));
  static tree lookup_anon_field PARAMS ((tree, tree));
  static tree pointer_diff PARAMS ((tree, tree, tree));
--- 54,60 ----
  static int comp_ptr_ttypes_const PARAMS ((tree, tree));
  static int comp_ptr_ttypes_reinterpret PARAMS ((tree, tree));
  static int comp_except_types PARAMS ((tree, tree, int));
! static bool comp_array_types PARAMS ((tree, tree, int));
  static tree common_base_type PARAMS ((tree, tree));
  static tree lookup_anon_field PARAMS ((tree, tree));
  static tree pointer_diff PARAMS ((tree, tree, tree));
*************** comp_except_specs (t1, t2, exact)
*** 837,848 ****
    return !exact || base == NULL_TREE || length == list_length (t1);
  }
  
! /* Compare the array types T1 and T2, using CMP as the type comparison
!    function for the element types.  STRICT is as for comptypes.  */
  
! static int
! comp_array_types (cmp, t1, t2, strict)
!      register int (*cmp) PARAMS ((tree, tree, int));
       tree t1, t2;
       int strict;
  {
--- 836,845 ----
    return !exact || base == NULL_TREE || length == list_length (t1);
  }
  
! /* Compare the array types T1 and T2.  STRICT is as for comptypes.  */
  
! static bool
! comp_array_types (t1, t2, strict)
       tree t1, t2;
       int strict;
  {
*************** comp_array_types (cmp, t1, t2, strict)
*** 853,868 ****
      return 1;
  
    /* The type of the array elements must be the same.  */
!   if (!(TREE_TYPE (t1) == TREE_TYPE (t2)
! 	|| (*cmp) (TREE_TYPE (t1), TREE_TYPE (t2), 
! 		   strict & ~COMPARE_REDECLARATION)))
!     return 0;
  
    d1 = TYPE_DOMAIN (t1);
    d2 = TYPE_DOMAIN (t2);
  
    if (d1 == d2)
!     return 1;
  
    /* If one of the arrays is dimensionless, and the other has a
       dimension, they are of different types.  However, it is valid to
--- 850,864 ----
      return 1;
  
    /* The type of the array elements must be the same.  */
!   if (!comptypes (TREE_TYPE (t1), TREE_TYPE (t2), 
! 		 strict & ~COMPARE_REDECLARATION))
!     return false;
  
    d1 = TYPE_DOMAIN (t1);
    d2 = TYPE_DOMAIN (t2);
  
    if (d1 == d2)
!     return true;
  
    /* If one of the arrays is dimensionless, and the other has a
       dimension, they are of different types.  However, it is valid to
*************** comp_array_types (cmp, t1, t2, strict)
*** 880,982 ****
      return strict & COMPARE_REDECLARATION;
  
    /* Check that the dimensions are the same.  */
!   return (cp_tree_equal (TYPE_MIN_VALUE (d1),
! 			 TYPE_MIN_VALUE (d2))
! 	  && cp_tree_equal (TYPE_MAX_VALUE (d1),
! 			    TYPE_MAX_VALUE (d2)));
  }
  
! /* Return 1 if T1 and T2 are compatible types for assignment or
!    various other operations.  STRICT is a bitwise-or of the COMPARE_*
!    flags.  */
  
! int
  comptypes (t1, t2, strict)
       tree t1;
       tree t2;
       int strict;
  {
-   int attrval, val;
    int orig_strict = strict;
  
-   /* The special exemption for redeclaring array types without an
-      array bound only applies at the top level:
- 
-        extern int (*i)[];
-        int (*i)[8];
- 
-      is invalid, for example.  */
-   strict &= ~COMPARE_REDECLARATION;
- 
-   /* Suppress errors caused by previously reported errors */
    if (t1 == t2)
!     return 1;
  
    /* This should never happen.  */
    my_friendly_assert (t1 != error_mark_node, 307);
  
    if (t2 == error_mark_node)
!     return 0;
  
!   /* If either type is the internal version of sizetype, return the
       language version.  */
    if (TREE_CODE (t1) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t1)
!       && TYPE_DOMAIN (t1) != 0)
      t1 = TYPE_DOMAIN (t1);
  
    if (TREE_CODE (t2) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t2)
!       && TYPE_DOMAIN (t2) != 0)
      t2 = TYPE_DOMAIN (t2);
  
-   if (strict & COMPARE_RELAXED)
-     {
-       /* Treat an enum type as the unsigned integer type of the same width.  */
- 
-       if (TREE_CODE (t1) == ENUMERAL_TYPE)
- 	t1 = c_common_type_for_size (TYPE_PRECISION (t1), 1);
-       if (TREE_CODE (t2) == ENUMERAL_TYPE)
- 	t2 = c_common_type_for_size (TYPE_PRECISION (t2), 1);
- 
-       if (t1 == t2)
- 	return 1;
-     }
- 
    if (TYPE_PTRMEMFUNC_P (t1))
      t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
    if (TYPE_PTRMEMFUNC_P (t2))
      t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
  
-   /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
-      current instantiation.  */
-   if (TREE_CODE (t1) == TYPENAME_TYPE)
-     t1 = resolve_typename_type_in_current_instantiation (t1);
-   if (TREE_CODE (t2) == TYPENAME_TYPE)
-     t2 = resolve_typename_type_in_current_instantiation (t2);
- 
    /* Different classes of types can't be compatible.  */
    if (TREE_CODE (t1) != TREE_CODE (t2))
!     return 0;
  
    /* Qualifiers must match.  */
    if (cp_type_quals (t1) != cp_type_quals (t2))
!     return 0;
!   if (strict == COMPARE_STRICT 
!       && TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
!     return 0;
  
    /* Allow for two different type nodes which have essentially the same
       definition.  Note that we already checked for equality of the type
       qualifiers (just above).  */
  
    if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
!     return 1;
  
!   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
!   if (! (attrval = (*targetm.comp_type_attributes) (t1, t2)))
!     return 0;
! 
!   /* 1 if no need for warning yet, 2 if warning cause has been seen.  */
!   val = 0;
  
    switch (TREE_CODE (t1))
      {
--- 876,960 ----
      return strict & COMPARE_REDECLARATION;
  
    /* Check that the dimensions are the same.  */
!   return (cp_tree_equal (TYPE_MIN_VALUE (d1), TYPE_MIN_VALUE (d2))
! 	  && cp_tree_equal (TYPE_MAX_VALUE (d1), TYPE_MAX_VALUE (d2)));
  }
  
! /* Return true if T1 and T2 are related as allowed by STRICT.  STRICT
!    is a bitwise-or of the COMPARE_* flags.  */
  
! bool
  comptypes (t1, t2, strict)
       tree t1;
       tree t2;
       int strict;
  {
    int orig_strict = strict;
  
    if (t1 == t2)
!     return true;
! 
!   strict &= ~(COMPARE_REDECLARATION | COMPARE_BASE | COMPARE_DERIVED);
  
    /* This should never happen.  */
    my_friendly_assert (t1 != error_mark_node, 307);
  
+   /* Suppress errors caused by previously reported errors */
    if (t2 == error_mark_node)
!     return false;
! 
!   /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
!      current instantiation.  */
!   if (TREE_CODE (t1) == TYPENAME_TYPE)
!     {
!       tree resolved = resolve_typename_type (t1, /*only_current_p=*/true);
! 
!       if (resolved != error_mark_node)
! 	t1 = resolved;
!     }
!   
!   if (TREE_CODE (t2) == TYPENAME_TYPE)
!     {
!       tree resolved = resolve_typename_type (t2, /*only_current_p=*/true);
! 
!       if (resolved != error_mark_node)
! 	t2 = resolved;
!     }
  
!   /* If either type is the internal version of sizetype, use the
       language version.  */
    if (TREE_CODE (t1) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t1)
!       && TYPE_DOMAIN (t1))
      t1 = TYPE_DOMAIN (t1);
  
    if (TREE_CODE (t2) == INTEGER_TYPE && TYPE_IS_SIZETYPE (t2)
!       && TYPE_DOMAIN (t2))
      t2 = TYPE_DOMAIN (t2);
  
    if (TYPE_PTRMEMFUNC_P (t1))
      t1 = TYPE_PTRMEMFUNC_FN_TYPE (t1);
    if (TYPE_PTRMEMFUNC_P (t2))
      t2 = TYPE_PTRMEMFUNC_FN_TYPE (t2);
  
    /* Different classes of types can't be compatible.  */
    if (TREE_CODE (t1) != TREE_CODE (t2))
!     return false;
  
    /* Qualifiers must match.  */
    if (cp_type_quals (t1) != cp_type_quals (t2))
!     return false;
!   if (TYPE_FOR_JAVA (t1) != TYPE_FOR_JAVA (t2))
!     return false;
  
    /* Allow for two different type nodes which have essentially the same
       definition.  Note that we already checked for equality of the type
       qualifiers (just above).  */
  
    if (TYPE_MAIN_VARIANT (t1) == TYPE_MAIN_VARIANT (t2))
!     return true;
  
!   if (!(*targetm.comp_type_attributes) (t1, t2))
!     return false;
  
    switch (TREE_CODE (t1))
      {
*************** comptypes (t1, t2, strict)
*** 984,1062 ****
      case BOUND_TEMPLATE_TEMPLATE_PARM:
        if (TEMPLATE_TYPE_IDX (t1) != TEMPLATE_TYPE_IDX (t2)
  	  || TEMPLATE_TYPE_LEVEL (t1) != TEMPLATE_TYPE_LEVEL (t2))
! 	return 0;
!       if (! comp_template_parms
! 	      (DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t1)),
! 	       DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t2))))
! 	return 0;
        if (TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM)
! 	return 1;
        /* Don't check inheritance.  */
!       strict = COMPARE_STRICT;
        /* fall through */
  
      case RECORD_TYPE:
      case UNION_TYPE:
        if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
  	  && (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
! 	      || TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM))
! 	val = comp_template_args (TYPE_TI_ARGS (t1),
! 				  TYPE_TI_ARGS (t2));
!     look_hard:
!       if ((strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2))
! 	val = 1;
!       else if ((strict & COMPARE_RELAXED) && DERIVED_FROM_P (t2, t1))
! 	val = 1;
!       break;
  
      case OFFSET_TYPE:
!       val = (comptypes (build_pointer_type (TYPE_OFFSET_BASETYPE (t1)),
! 			build_pointer_type (TYPE_OFFSET_BASETYPE (t2)), strict)
! 	     && comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict));
!       break;
  
      case POINTER_TYPE:
      case REFERENCE_TYPE:
!       t1 = TREE_TYPE (t1);
!       t2 = TREE_TYPE (t2);
!       /* first, check whether the referred types match with the
!          required level of strictness */
!       val = comptypes (t1, t2, strict);
!       if (val)
! 	break;
!       if (TREE_CODE (t1) == RECORD_TYPE 
! 	  && TREE_CODE (t2) == RECORD_TYPE)
! 	goto look_hard;
!       break;
  
      case METHOD_TYPE:
      case FUNCTION_TYPE:
!       val = ((TREE_TYPE (t1) == TREE_TYPE (t2)
! 	      || comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict))
! 	     && compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2)));
!       break;
  
      case ARRAY_TYPE:
        /* Target types must match incl. qualifiers.  We use ORIG_STRICT
  	 here since this is the one place where
  	 COMPARE_REDECLARATION should be used.  */
!       val = comp_array_types (comptypes, t1, t2, orig_strict);
!       break;
  
      case TEMPLATE_TYPE_PARM:
!       return TEMPLATE_TYPE_IDX (t1) == TEMPLATE_TYPE_IDX (t2)
! 	&& TEMPLATE_TYPE_LEVEL (t1) == TEMPLATE_TYPE_LEVEL (t2);
  
      case TYPENAME_TYPE:
!       if (cp_tree_equal (TYPENAME_TYPE_FULLNAME (t1),
!                          TYPENAME_TYPE_FULLNAME (t2)) < 1)
!         return 0;
        return same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2));
  
      case UNBOUND_CLASS_TEMPLATE:
!       if (cp_tree_equal (TYPE_IDENTIFIER (t1),
!                          TYPE_IDENTIFIER (t2)) < 1)
!         return 0;
        return same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2));
  
      case COMPLEX_TYPE:
--- 962,1028 ----
      case BOUND_TEMPLATE_TEMPLATE_PARM:
        if (TEMPLATE_TYPE_IDX (t1) != TEMPLATE_TYPE_IDX (t2)
  	  || TEMPLATE_TYPE_LEVEL (t1) != TEMPLATE_TYPE_LEVEL (t2))
! 	return false;
!       if (!comp_template_parms
! 	  (DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t1)),
! 	   DECL_TEMPLATE_PARMS (TEMPLATE_TEMPLATE_PARM_TEMPLATE_DECL (t2))))
! 	return false;
        if (TREE_CODE (t1) == TEMPLATE_TEMPLATE_PARM)
! 	return true;
        /* Don't check inheritance.  */
!       orig_strict = COMPARE_STRICT;
        /* fall through */
  
      case RECORD_TYPE:
      case UNION_TYPE:
        if (TYPE_TEMPLATE_INFO (t1) && TYPE_TEMPLATE_INFO (t2)
  	  && (TYPE_TI_TEMPLATE (t1) == TYPE_TI_TEMPLATE (t2)
! 	      || TREE_CODE (t1) == BOUND_TEMPLATE_TEMPLATE_PARM)
! 	  && comp_template_args (TYPE_TI_ARGS (t1), TYPE_TI_ARGS (t2)))
! 	return true;
!       
!       if ((orig_strict & COMPARE_BASE) && DERIVED_FROM_P (t1, t2))
! 	return true;
!       else if ((orig_strict & COMPARE_DERIVED) && DERIVED_FROM_P (t2, t1))
! 	return true;
!       
!       return false;
  
      case OFFSET_TYPE:
!       if (!comptypes (TYPE_OFFSET_BASETYPE (t1), TYPE_OFFSET_BASETYPE (t2),
! 		      orig_strict))
! 	return false;
!       return comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict);
  
      case POINTER_TYPE:
      case REFERENCE_TYPE:
!       return comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict);
  
      case METHOD_TYPE:
      case FUNCTION_TYPE:
!       if (!comptypes (TREE_TYPE (t1), TREE_TYPE (t2), strict))
! 	return false;
!       return compparms (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2));
  
      case ARRAY_TYPE:
        /* Target types must match incl. qualifiers.  We use ORIG_STRICT
  	 here since this is the one place where
  	 COMPARE_REDECLARATION should be used.  */
!       return comp_array_types (t1, t2, orig_strict & COMPARE_REDECLARATION);
  
      case TEMPLATE_TYPE_PARM:
!       return (TEMPLATE_TYPE_IDX (t1) == TEMPLATE_TYPE_IDX (t2)
! 	      && TEMPLATE_TYPE_LEVEL (t1) == TEMPLATE_TYPE_LEVEL (t2));
  
      case TYPENAME_TYPE:
!       if (!cp_tree_equal (TYPENAME_TYPE_FULLNAME (t1),
! 			  TYPENAME_TYPE_FULLNAME (t2)))
!         return false;
        return same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2));
  
      case UNBOUND_CLASS_TEMPLATE:
!       if (!cp_tree_equal (TYPE_IDENTIFIER (t1), TYPE_IDENTIFIER (t2)))
!         return false;
        return same_type_p (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2));
  
      case COMPLEX_TYPE:
*************** comptypes (t1, t2, strict)
*** 1065,1071 ****
      default:
        break;
      }
!   return attrval == 2 && val == 1 ? 2 : val;
  }
  
  /* Subroutine of comp_target-types.  Make sure that the cv-quals change
--- 1031,1037 ----
      default:
        break;
      }
!   return false;
  }
  
  /* Subroutine of comp_target-types.  Make sure that the cv-quals change
*************** comp_target_types (ttl, ttr, nptrs)
*** 1166,1174 ****
        return comp_cv_target_types (ttl, ttr, nptrs - 1);
      }
  
!   if (TREE_CODE (ttr) == ARRAY_TYPE)
!     return comp_array_types (comp_target_types, ttl, ttr, COMPARE_STRICT);
!   else if (TREE_CODE (ttr) == FUNCTION_TYPE || TREE_CODE (ttr) == METHOD_TYPE)
      {
        tree argsl, argsr;
        int saw_contra = 0;
--- 1132,1139 ----
        return comp_cv_target_types (ttl, ttr, nptrs - 1);
      }
  
!   my_friendly_assert (TREE_CODE (ttr) != ARRAY_TYPE, 20030617);
!   if (TREE_CODE (ttr) == FUNCTION_TYPE || TREE_CODE (ttr) == METHOD_TYPE)
      {
        tree argsl, argsr;
        int saw_contra = 0;
*************** comp_target_types (ttl, ttr, nptrs)
*** 1263,1273 ****
      {
        if (nptrs < 0)
  	return 0;
!       if (same_or_base_type_p (build_pointer_type (ttl), 
! 			       build_pointer_type (ttr)))
  	return 1;
!       if (same_or_base_type_p (build_pointer_type (ttr), 
! 			       build_pointer_type (ttl)))
  	return -1;
        return 0;
      }
--- 1228,1236 ----
      {
        if (nptrs < 0)
  	return 0;
!       if (same_or_base_type_p (ttl, ttr))
  	return 1;
!       if (same_or_base_type_p (ttr, ttl))
  	return -1;
        return 0;
      }
*************** comp_target_parms (parms1, parms2)
*** 1454,1462 ****
      {
        tree p1, p2;
  
!       /* If one parmlist is shorter than the other,
! 	 they fail to match, unless STRICT is <= 0.  */
!       if (t1 == 0 || t2 == 0)
  	return 0;
        p1 = TREE_VALUE (t1);
        p2 = TREE_VALUE (t2);
--- 1417,1424 ----
      {
        tree p1, p2;
  
!       /* If one parmlist is shorter than the other, they fail to match.  */
!       if (!t1 || !t2)
  	return 0;
        p1 = TREE_VALUE (t1);
        p2 = TREE_VALUE (t2);
*************** maybe_warn_about_returning_address_of_lo
*** 6313,6320 ****
        if (TREE_CODE (whats_returned) == AGGR_INIT_EXPR
  	  || TREE_CODE (whats_returned) == TARGET_EXPR)
  	{
- 	  /* Get the target.  */
- 	  whats_returned = TREE_OPERAND (whats_returned, 0);
  	  warning ("returning reference to temporary");
  	  return;
  	}
--- 6275,6280 ----
*************** check_return_expr (retval)
*** 6402,6408 ****
       that's supposed to return a value.  */
    if (!retval && fn_returns_value_p)
      {
!       pedwarn ("return-statement with no value, in function declared with a non-void return type");
        /* Clear this, so finish_function won't say that we reach the
  	 end of a non-void function (which we don't, we gave a
  	 return!).  */
--- 6362,6369 ----
       that's supposed to return a value.  */
    if (!retval && fn_returns_value_p)
      {
!       pedwarn ("return-statement with no value, in function returning `%D'",
! 	       valtype);
        /* Clear this, so finish_function won't say that we reach the
  	 end of a non-void function (which we don't, we gave a
  	 return!).  */
*************** check_return_expr (retval)
*** 6418,6424 ****
  	   its side-effects.  */
  	  finish_expr_stmt (retval);
        else
! 	pedwarn ("return-statement with a value, in function declared with a void return type");
  
        current_function_returns_null = 1;
  
--- 6379,6386 ----
  	   its side-effects.  */
  	  finish_expr_stmt (retval);
        else
! 	pedwarn ("return-statement with a value, in function returning `%D'",
! 		 retval);
  
        current_function_returns_null = 1;
  
*************** ptr_reasonably_similar (to, from)
*** 6610,6616 ****
        if (TREE_CODE (from) == OFFSET_TYPE
  	  && comptypes (TYPE_OFFSET_BASETYPE (to),
  			TYPE_OFFSET_BASETYPE (from), 
! 			COMPARE_BASE | COMPARE_RELAXED))
  	continue;
  
        if (TREE_CODE (to) == INTEGER_TYPE
--- 6572,6578 ----
        if (TREE_CODE (from) == OFFSET_TYPE
  	  && comptypes (TYPE_OFFSET_BASETYPE (to),
  			TYPE_OFFSET_BASETYPE (from), 
! 			COMPARE_BASE | COMPARE_DERIVED))
  	continue;
  
        if (TREE_CODE (to) == INTEGER_TYPE
*************** ptr_reasonably_similar (to, from)
*** 6623,6629 ****
        if (TREE_CODE (to) != POINTER_TYPE)
  	return comptypes
  	  (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), 
! 	   COMPARE_BASE | COMPARE_RELAXED);
      }
  }
  
--- 6585,6591 ----
        if (TREE_CODE (to) != POINTER_TYPE)
  	return comptypes
  	  (TYPE_MAIN_VARIANT (to), TYPE_MAIN_VARIANT (from), 
! 	   COMPARE_BASE | COMPARE_DERIVED);
      }
  }
  

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