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] type safety


Hi,
We were passing non-types to same_type_p. This patch cleans that up.
BTW, if we had compile time type safe trees, this would never have happened.

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-24  Nathan Sidwell  <nathan@codesourcery.com>

	* call.c (enforce_access): Assert we get a binfo.
	(build_op_delete_call): Pass a binfo to
	perform_or_defer_access_check.
	* class.c (alter_access): Likewise.
	* decl.c (make_typename_type): Likewise.
	(make_unbound_class_template): Likewise.
	* lex.c (do_identifier): Likewise.
	* method.c (hack_identifier): Likewise.
	* parser.c (cp_parser_lookup_name): Likewise.
	* search.c (lookup_member): Likewise. Move IDENTIFIER_CLASS_VALUE
	test.
	* semantics.c (finish_non_static_data_member): Likewise.
	(perform_or_defer_access_check): Expect a binfo.
	* typeck.c (comptypes): Expect types.

	* mangle.c (find_substitution): Don't pass a non-type to same_type_p
	* friend.c (make_friend_class): Likewise.
	* pt.c (check_default_tmpl_args): Likewise.
	(lookup_template_class): Likewise.

Index: cp/call.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/call.c,v
retrieving revision 1.390
diff -c -3 -p -r1.390 call.c
*** cp/call.c	21 Jun 2003 17:39:57 -0000	1.390
--- cp/call.c	24 Jun 2003 15:01:52 -0000
*************** build_op_delete_call (enum tree_code cod
*** 4071,4077 ****
        /* If the FN is a member function, make sure that it is
  	 accessible.  */
        if (DECL_CLASS_SCOPE_P (fn))
! 	perform_or_defer_access_check (type, fn);
  
        if (pass == 0)
  	args = tree_cons (NULL_TREE, addr, args);
--- 4071,4077 ----
        /* If the FN is a member function, make sure that it is
  	 accessible.  */
        if (DECL_CLASS_SCOPE_P (fn))
! 	perform_or_defer_access_check (TYPE_BINFO (type), fn);
  
        if (pass == 0)
  	args = tree_cons (NULL_TREE, addr, args);
*************** build_op_delete_call (enum tree_code cod
*** 4098,4103 ****
--- 4098,4105 ----
  bool
  enforce_access (tree basetype_path, tree decl)
  {
+   my_friendly_assert (TREE_CODE (basetype_path) == TREE_VEC, 20030624);
+   
    if (!accessible_p (basetype_path, decl))
      {
        if (TREE_PRIVATE (decl))
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.543
diff -c -3 -p -r1.543 class.c
*** cp/class.c	17 Jun 2003 22:24:57 -0000	1.543
--- cp/class.c	24 Jun 2003 15:02:09 -0000
*************** alter_access (tree t, tree fdecl, tree a
*** 1063,1070 ****
    if (!DECL_LANG_SPECIFIC (fdecl))
      retrofit_lang_decl (fdecl);
  
!   if (DECL_DISCRIMINATOR_P (fdecl))
!     abort ();
  
    elem = purpose_member (t, DECL_ACCESS (fdecl));
    if (elem)
--- 1063,1069 ----
    if (!DECL_LANG_SPECIFIC (fdecl))
      retrofit_lang_decl (fdecl);
  
!   my_friendly_assert (!DECL_DISCRIMINATOR_P (fdecl), 20030624);
  
    elem = purpose_member (t, DECL_ACCESS (fdecl));
    if (elem)
*************** alter_access (tree t, tree fdecl, tree a
*** 1086,1092 ****
      }
    else
      {
!       perform_or_defer_access_check (t, fdecl);
        DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
        return 1;
      }
--- 1085,1091 ----
      }
    else
      {
!       perform_or_defer_access_check (TYPE_BINFO (t), fdecl);
        DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
        return 1;
      }
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1070
diff -c -3 -p -r1.1070 decl.c
*** cp/decl.c	21 Jun 2003 13:09:05 -0000	1.1070
--- cp/decl.c	24 Jun 2003 15:02:40 -0000
*************** make_typename_type (tree context, tree n
*** 5525,5531 ****
  	    }
  
  	  if (complain & tf_error)
! 	    perform_or_defer_access_check (context, tmpl);
  
  	  return lookup_template_class (tmpl,
  					TREE_OPERAND (fullname, 1),
--- 5525,5531 ----
  	    }
  
  	  if (complain & tf_error)
! 	    perform_or_defer_access_check (TYPE_BINFO (context), tmpl);
  
  	  return lookup_template_class (tmpl,
  					TREE_OPERAND (fullname, 1),
*************** make_typename_type (tree context, tree n
*** 5555,5561 ****
  		}
  
  	      if (complain & tf_error)
! 		perform_or_defer_access_check (context, t);
  
  	      if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl))
  		t = TREE_TYPE (t);
--- 5555,5561 ----
  		}
  
  	      if (complain & tf_error)
! 		perform_or_defer_access_check (TYPE_BINFO (context), t);
  
  	      if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl))
  		t = TREE_TYPE (t);
*************** make_unbound_class_template (tree contex
*** 5612,5618 ****
  	}
        
        if (complain & tf_error)
! 	perform_or_defer_access_check (context, tmpl);
  
        return tmpl;
      }
--- 5612,5618 ----
  	}
        
        if (complain & tf_error)
! 	perform_or_defer_access_check (TYPE_BINFO (context), tmpl);
  
        return tmpl;
      }
Index: cp/friend.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/friend.c,v
retrieving revision 1.82
diff -c -3 -p -r1.82 friend.c
*** cp/friend.c	11 Mar 2003 15:43:14 -0000	1.82
--- cp/friend.c	24 Jun 2003 15:02:41 -0000
*************** make_friend_class (type, friend_type)
*** 264,280 ****
    if (is_template_friend)
      friend_type = CLASSTYPE_TI_TEMPLATE (friend_type);
  
!   classes = CLASSTYPE_FRIEND_CLASSES (type);
!   while (classes 
! 	 /* Stop if we find the same type on the list.  */
! 	 && !(TREE_CODE (TREE_VALUE (classes)) == TEMPLATE_DECL ?
! 	      friend_type == TREE_VALUE (classes) :
! 	      same_type_p (TREE_VALUE (classes), friend_type)))
!     classes = TREE_CHAIN (classes);
!   if (classes) 
!     warning ("`%T' is already a friend of `%T'",
! 		TREE_VALUE (classes), type);
!   else
      {
        maybe_add_class_template_decl_list (type, friend_type, /*friend_p=*/1);
  
--- 264,297 ----
    if (is_template_friend)
      friend_type = CLASSTYPE_TI_TEMPLATE (friend_type);
  
!   /* See if it is already a friend.  */
!   for (classes = CLASSTYPE_FRIEND_CLASSES (type);
!        classes;
!        classes = TREE_CHAIN (classes))
!     {
!       tree probe = TREE_VALUE (classes);
! 
!       if (TREE_CODE (friend_type) == TEMPLATE_DECL)
! 	{
! 	  if (friend_type == probe)
! 	    {
! 	      warning ("`%D' is already a friend of `%T'",
! 		       probe, type);
! 	      break;
! 	    }
! 	}
!       else if (TREE_CODE (probe) != TEMPLATE_DECL)
! 	{
! 	  if (same_type_p (probe, friend_type))
! 	    {
! 	      warning ("`%T' is already a friend of `%T'",
! 		       probe, type);
! 	      break;
! 	    }
! 	}
!     }
!   
!   if (!classes) 
      {
        maybe_add_class_template_decl_list (type, friend_type, /*friend_p=*/1);
  
Index: cp/lex.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/lex.c,v
retrieving revision 1.306
diff -c -3 -p -r1.306 lex.c
*** cp/lex.c	13 Jun 2003 16:13:06 -0000	1.306
--- cp/lex.c	24 Jun 2003 15:02:53 -0000
*************** do_identifier (register tree token, tree
*** 777,783 ****
      {
        /* Check access.  */
        if (IDENTIFIER_CLASS_VALUE (token) == id)
! 	perform_or_defer_access_check (CP_DECL_CONTEXT(id), id);
        if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id))
  	id = DECL_INITIAL (id);
      }
--- 777,783 ----
      {
        /* Check access.  */
        if (IDENTIFIER_CLASS_VALUE (token) == id)
! 	perform_or_defer_access_check (TYPE_BINFO (DECL_CONTEXT (id)), id);
        if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id))
  	id = DECL_INITIAL (id);
      }
Index: cp/mangle.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/mangle.c,v
retrieving revision 1.75
diff -c -3 -p -r1.75 mangle.c
*** cp/mangle.c	18 Jun 2003 06:29:58 -0000	1.75
--- cp/mangle.c	24 Jun 2003 15:02:56 -0000
*************** find_substitution (tree node)
*** 546,551 ****
--- 546,552 ----
  	 args <char, std::char_traits<char> > .  */
        tree args = CLASSTYPE_TI_ARGS (type);
        if (TREE_VEC_LENGTH (args) == 2
+ 	  && TYPE_P (TREE_VEC_ELT (args, 0))
  	  && same_type_p (TREE_VEC_ELT (args, 0), char_type_node)
  	  && is_std_substitution_char (TREE_VEC_ELT (args, 1),
  				       SUBID_CHAR_TRAITS))
Index: cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.253
diff -c -3 -p -r1.253 method.c
*** cp/method.c	16 Jun 2003 13:15:37 -0000	1.253
--- cp/method.c	24 Jun 2003 15:02:58 -0000
*************** hack_identifier (tree value, tree name)
*** 179,185 ****
  	{
  	  tree path;
  	  path = currently_open_derived_class (DECL_CONTEXT (value));
! 	  perform_or_defer_access_check (path, value);
  	}
      }
    else if (TREE_CODE (value) == TREE_LIST 
--- 179,185 ----
  	{
  	  tree path;
  	  path = currently_open_derived_class (DECL_CONTEXT (value));
! 	  perform_or_defer_access_check (TYPE_BINFO (path), value);
  	}
      }
    else if (TREE_CODE (value) == TREE_LIST 
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.65
diff -c -3 -p -r1.65 parser.c
*** cp/parser.c	20 Jun 2003 18:55:44 -0000	1.65
--- cp/parser.c	24 Jun 2003 15:03:29 -0000
*************** cp_parser_lookup_name (cp_parser *parser
*** 13353,13359 ****
  						       object_type,
  						       parser->scope);
        if (qualifying_type)
! 	perform_or_defer_access_check (qualifying_type, decl);
      }
  
    return decl;
--- 13353,13359 ----
  						       object_type,
  						       parser->scope);
        if (qualifying_type)
! 	perform_or_defer_access_check (TYPE_BINFO (qualifying_type), decl);
      }
  
    return decl;
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.704
diff -c -3 -p -r1.704 pt.c
*** cp/pt.c	20 Jun 2003 15:44:22 -0000	1.704
--- cp/pt.c	24 Jun 2003 15:03:54 -0000
*************** check_default_tmpl_args (tree decl, tree
*** 2528,2541 ****
        && DECL_LANG_SPECIFIC (decl)
        /* If this is either a friend defined in the scope of the class
  	 or a member function.  */
!       && ((DECL_CONTEXT (decl) 
! 	   && same_type_p (DECL_CONTEXT (decl), current_class_type))
! 	  || (DECL_FRIEND_CONTEXT (decl)
! 	      && same_type_p (DECL_FRIEND_CONTEXT (decl), 
! 			      current_class_type)))
        /* And, if it was a member function, it really was defined in
  	 the scope of the class.  */
!       && (!DECL_FUNCTION_MEMBER_P (decl) || DECL_INITIALIZED_IN_CLASS_P (decl)))
      /* We already checked these parameters when the template was
         declared, so there's no need to do it again now.  This function
         was defined in class scope, but we're processing it's body now
--- 2528,2542 ----
        && DECL_LANG_SPECIFIC (decl)
        /* If this is either a friend defined in the scope of the class
  	 or a member function.  */
!       && (DECL_FUNCTION_MEMBER_P (decl)
! 	  ? same_type_p (DECL_CONTEXT (decl), current_class_type)
! 	  : DECL_FRIEND_CONTEXT (decl)
! 	  ? same_type_p (DECL_FRIEND_CONTEXT (decl), current_class_type)
! 	  : false)
        /* And, if it was a member function, it really was defined in
  	 the scope of the class.  */
!       && (!DECL_FUNCTION_MEMBER_P (decl)
! 	  || DECL_INITIALIZED_IN_CLASS_P (decl)))
      /* We already checked these parameters when the template was
         declared, so there's no need to do it again now.  This function
         was defined in class scope, but we're processing it's body now
*************** lookup_template_class (tree d1, 
*** 4234,4254 ****
  	    {
  	      tree ctx;
  	      
- 	      /* Note that we use DECL_CONTEXT, rather than
- 		 CP_DECL_CONTEXT, so that the termination test is
- 		 always just `ctx'.  We're not interested in namespace
- 		 scopes.  */
  	      for (ctx = current_class_type; 
  		   ctx; 
! 		   ctx = (TYPE_P (ctx)) ? TYPE_CONTEXT (ctx) : DECL_CONTEXT (ctx))
! 		if (same_type_p (ctx, template_type))
! 		  break;
  	      
! 	      if (!ctx)
! 		/* We're not in the scope of the class, so the
! 		   TEMPLATE_TYPE is not the type we want after
! 		   all.  */
! 		found = NULL_TREE;
  	    }
  	}
        if (found)
--- 4235,4254 ----
  	    {
  	      tree ctx;
  	      
  	      for (ctx = current_class_type; 
  		   ctx; 
! 		   ctx = TYPE_CONTEXT (ctx))
! 		{
! 		  if (TREE_CODE (ctx) == NAMESPACE_DECL)
! 		    break;
! 		  if (same_type_p (ctx, template_type))
! 		    goto found_ctx;
! 		}
  	      
! 	      /* We're not in the scope of the class, so the
! 		 TEMPLATE_TYPE is not the type we want after all.  */
! 	      found = NULL_TREE;
! 	    found_ctx:;
  	    }
  	}
        if (found)
Index: cp/search.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/search.c,v
retrieving revision 1.265
diff -c -3 -p -r1.265 search.c
*** cp/search.c	17 Jun 2003 16:58:17 -0000	1.265
--- cp/search.c	24 Jun 2003 15:04:00 -0000
*************** lookup_member (tree xbasetype, tree name
*** 1226,1260 ****
  
    const char *errstr = 0;
  
!   /* Sanity check.  */
!   if (TREE_CODE (name) != IDENTIFIER_NODE)
!     abort ();
! 
!   if (xbasetype == current_class_type && TYPE_BEING_DEFINED (xbasetype)
!       && IDENTIFIER_CLASS_VALUE (name))
!     {
!       tree field = IDENTIFIER_CLASS_VALUE (name);
!       if (! is_overloaded_fn (field)
! 	  && ! (want_type && TREE_CODE (field) != TYPE_DECL))
! 	/* We're in the scope of this class, and the value has already
! 	   been looked up.  Just return the cached value.  */
! 	return field;
!     }
  
    if (TREE_CODE (xbasetype) == TREE_VEC)
      {
        type = BINFO_TYPE (xbasetype);
        basetype_path = xbasetype;
      }
!   else if (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)))
      {
        type = xbasetype;
        basetype_path = TYPE_BINFO (type);
!       my_friendly_assert (BINFO_INHERITANCE_CHAIN (basetype_path) == NULL_TREE,
! 			  980827);
      }
-   else
-     abort ();
  
    complete_type (type);
  
--- 1226,1256 ----
  
    const char *errstr = 0;
  
!   my_friendly_assert (TREE_CODE (name) == IDENTIFIER_NODE, 20030624);
  
    if (TREE_CODE (xbasetype) == TREE_VEC)
      {
        type = BINFO_TYPE (xbasetype);
        basetype_path = xbasetype;
      }
!   else
      {
+       my_friendly_assert (IS_AGGR_TYPE_CODE (TREE_CODE (xbasetype)), 20030624);
        type = xbasetype;
        basetype_path = TYPE_BINFO (type);
!       my_friendly_assert (!BINFO_INHERITANCE_CHAIN (basetype_path), 980827);
!     }
! 
!   if (type == current_class_type && TYPE_BEING_DEFINED (type)
!       && IDENTIFIER_CLASS_VALUE (name))
!     {
!       tree field = IDENTIFIER_CLASS_VALUE (name);
!       if (! is_overloaded_fn (field)
! 	  && ! (want_type && TREE_CODE (field) != TYPE_DECL))
! 	/* We're in the scope of this class, and the value has already
! 	   been looked up.  Just return the cached value.  */
! 	return field;
      }
  
    complete_type (type);
  
*************** lookup_member (tree xbasetype, tree name
*** 1291,1297 ****
       In the case of overloaded function names, access control is
       applied to the function selected by overloaded resolution.  */
    if (rval && protect && !is_overloaded_fn (rval))
!     perform_or_defer_access_check (xbasetype, rval);
  
    if (errstr && protect)
      {
--- 1287,1293 ----
       In the case of overloaded function names, access control is
       applied to the function selected by overloaded resolution.  */
    if (rval && protect && !is_overloaded_fn (rval))
!     perform_or_defer_access_check (basetype_path, rval);
  
    if (errstr && protect)
      {
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.313
diff -c -3 -p -r1.313 semantics.c
*** cp/semantics.c	20 Jun 2003 09:08:20 -0000	1.313
--- cp/semantics.c	24 Jun 2003 15:04:05 -0000
*************** void perform_deferred_access_checks (voi
*** 262,277 ****
  }
  
  /* Defer checking the accessibility of DECL, when looked up in
!    CLASS_TYPE.  */
  
! void perform_or_defer_access_check (tree class_type, tree decl)
  {
    tree check;
  
    /* If we are not supposed to defer access checks, just check now.  */
    if (deferred_access_stack->deferring_access_checks_kind == dk_no_deferred)
      {
!       enforce_access (class_type, decl);
        return;
      }
    /* Exit if we are in a context that no access checking is performed.  */
--- 262,279 ----
  }
  
  /* Defer checking the accessibility of DECL, when looked up in
!    BINFO.  */
  
! void perform_or_defer_access_check (tree binfo, tree decl)
  {
    tree check;
  
+   my_friendly_assert (TREE_CODE (binfo) == TREE_VEC, 20030623);
+   
    /* If we are not supposed to defer access checks, just check now.  */
    if (deferred_access_stack->deferring_access_checks_kind == dk_no_deferred)
      {
!       enforce_access (binfo, decl);
        return;
      }
    /* Exit if we are in a context that no access checking is performed.  */
*************** void perform_or_defer_access_check (tree
*** 282,294 ****
    for (check = deferred_access_stack->deferred_access_checks;
         check;
         check = TREE_CHAIN (check))
!     if (TREE_VALUE (check) == decl
! 	&& TYPE_P (TREE_PURPOSE (check))
! 	&& same_type_p (TREE_PURPOSE (check), class_type))
        return;
    /* If not, record the check.  */
    deferred_access_stack->deferred_access_checks
!     = tree_cons (class_type, decl,
  		 deferred_access_stack->deferred_access_checks);
  }
  
--- 284,294 ----
    for (check = deferred_access_stack->deferred_access_checks;
         check;
         check = TREE_CHAIN (check))
!     if (TREE_VALUE (check) == decl && TREE_PURPOSE (check) == binfo)
        return;
    /* If not, record the check.  */
    deferred_access_stack->deferred_access_checks
!     = tree_cons (binfo, decl,
  		 deferred_access_stack->deferred_access_checks);
  }
  
*************** finish_non_static_data_member (tree decl
*** 1255,1261 ****
  	  return error_mark_node;
  	}
  
!       perform_or_defer_access_check (access_type, decl);
  
        /* If the data member was named `C::M', convert `*this' to `C'
  	 first.  */
--- 1255,1261 ----
  	  return error_mark_node;
  	}
  
!       perform_or_defer_access_check (TYPE_BINFO (access_type), decl);
  
        /* If the data member was named `C::M', convert `*this' to `C'
  	 first.  */
Index: cp/typeck.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/typeck.c,v
retrieving revision 1.466
diff -c -3 -p -r1.466 typeck.c
*** cp/typeck.c	18 Jun 2003 19:17:04 -0000	1.466
--- cp/typeck.c	24 Jun 2003 15:04:19 -0000
*************** comptypes (tree t1, tree t2, int strict)
*** 883,889 ****
    /* 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)
--- 883,891 ----
    /* Suppress errors caused by previously reported errors */
    if (t2 == error_mark_node)
      return false;
!   
!   my_friendly_assert (TYPE_P (t1) && TYPE_P (t2), 20030623);
!   
    /* TYPENAME_TYPEs should be resolved if the qualifying scope is the
       current instantiation.  */
    if (TREE_CODE (t1) == TYPENAME_TYPE)

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