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]

[4.0] Backport C++ patches


I've installed this set of patches to the now unfrozen 4.0 branch, backported from mainline.

booted & tested on i686-pc-linux-gnu

nathan
--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

Index: cp/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/ChangeLog,v
retrieving revision 1.4648.2.60
diff -c -3 -p -r1.4648.2.60 ChangeLog
*** cp/ChangeLog	7 Jul 2005 18:38:42 -0000	1.4648.2.60
--- cp/ChangeLog	12 Jul 2005 11:12:57 -0000
***************
*** 1,3 ****
--- 1,35 ----
+ 2005-07-11  Nathan Sidwell  <nathan@codesourcery.com>
+ 
+ 	PR c++/20678
+ 	* error.c (dump_expr) <COMPONENT_REF case>: Check DECL_NAME is not
+ 	null.
+ 
+ 	PR 21903
+ 	* cp-tree.def (DEFAULT_ARG): Document TREE_CHAIN use.
+ 	* parser.c (cp_parser_late_parsing_default_args): Propagate parsed
+ 	argument to any early instantiations.
+ 	* pt.c (tsubst_arg_types): Chain early instantiation of default
+ 	arg.
+ 
+ 	PR c++/20789
+ 	* decl.c (cp_finish_decl): Clear runtime runtime initialization if
+ 	in-class decl's initializer is bad.
+ 	
+ 	PR c++/21929
+ 	* parser.c (struct cp_parser): Document that scope could be
+ 	error_mark.
+ 	(cp_parser_diagnose_invalid_type_name): Cope with error_mark for
+ 	scope.
+ 	(cp_parser_nested_name_specifier): Return NULL_TREE on error.
+ 	(cp_parser_postfix_expression): Deal with null or error_mark
+ 	scope.
+ 	(cp_parser_elaborated_type_specifier): Adjust
+ 	cp_parser_nested_name_specifier call.
+ 	
+ 	PR c++/20746
+ 	* method.c (use_thunk): Protect covariant pointer return
+ 	adjustments from NULL pointers.
+ 
  2005-07-07  Release Manager
  
  	* GCC 4.0.1 released.
Index: cp/class.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/class.c,v
retrieving revision 1.707.2.3
diff -c -3 -p -r1.707.2.3 class.c
*** cp/class.c	24 Apr 2005 12:46:26 -0000	1.707.2.3
--- cp/class.c	12 Jul 2005 11:12:59 -0000
*************** modify_vtable_entry (tree t,
*** 878,889 ****
  }
  
  
! /* Add method METHOD to class TYPE.  */
  
  void
! add_method (tree type, tree method)
  {
-   int using;
    unsigned slot;
    tree overload;
    bool template_conv_p = false;
--- 878,889 ----
  }
  
  
! /* Add method METHOD to class TYPE.  If USING_DECL is non-null, it is
!    the USING_DECL naming METHOD.  */
  
  void
! add_method (tree type, tree method, tree using_decl)
  {
    unsigned slot;
    tree overload;
    bool template_conv_p = false;
*************** add_method (tree type, tree method)
*** 897,903 ****
      return;
  
    complete_p = COMPLETE_TYPE_P (type);
-   using = (DECL_CONTEXT (method) != type);
    conv_p = DECL_CONV_FN_P (method);
    if (conv_p)
      template_conv_p = (TREE_CODE (method) == TEMPLATE_DECL
--- 897,902 ----
*************** add_method (tree type, tree method)
*** 1024,1044 ****
  		  || same_type_p (TREE_TYPE (TREE_TYPE (fn)),
  				  TREE_TYPE (TREE_TYPE (method)))))
  	    {
! 	      if (using && DECL_CONTEXT (fn) == type)
! 		/* Defer to the local function.  */
! 		return;
  	      else
  		{
! 		  cp_error_at ("%q#D and %q#D cannot be overloaded",
! 			       method, fn);
! 
! 		  /* We don't call duplicate_decls here to merge
! 		     the declarations because that will confuse
! 		     things if the methods have inline
! 		     definitions.  In particular, we will crash
! 		     while processing the definitions.  */
! 		  return;
  		}
  	    }
  	}
      }
--- 1023,1050 ----
  		  || same_type_p (TREE_TYPE (TREE_TYPE (fn)),
  				  TREE_TYPE (TREE_TYPE (method)))))
  	    {
! 	      if (using_decl)
! 		{
! 		  if (DECL_CONTEXT (fn) == type)
! 		    /* Defer to the local function.  */
! 		    return;
! 		  if (DECL_CONTEXT (fn) == DECL_CONTEXT (method))
! 		    cp_error_at ("repeated using declaration %qD", using_decl);
! 		  else
! 		    cp_error_at ("using declaration %qD conflicts with a previous using declaration",
! 				 using_decl);
! 		}
  	      else
  		{
! 		  cp_error_at ("%q#D cannot be overloaded", method);
! 		  cp_error_at ("with %q#D", fn);
  		}
+ 	      
+ 	      /* We don't call duplicate_decls here to merge the
+ 		 declarations because that will confuse things if the
+ 		 methods have inline definitions.  In particular, we
+ 		 will crash while processing the definitions.  */
+ 	      return;
  	    }
  	}
      }
*************** handle_using_decl (tree using_decl, tree
*** 1201,1207 ****
    if (flist)
      for (; flist; flist = OVL_NEXT (flist))
        {
! 	add_method (t, OVL_CURRENT (flist));
  	alter_access (t, OVL_CURRENT (flist), access);
        }
    else
--- 1207,1213 ----
    if (flist)
      for (; flist; flist = OVL_NEXT (flist))
        {
! 	add_method (t, OVL_CURRENT (flist), using_decl);
  	alter_access (t, OVL_CURRENT (flist), access);
        }
    else
*************** clone_function_decl (tree fn, int update
*** 3829,3838 ****
  	 and a not-in-charge version.  */
        clone = build_clone (fn, complete_ctor_identifier);
        if (update_method_vec_p)
! 	add_method (DECL_CONTEXT (clone), clone);
        clone = build_clone (fn, base_ctor_identifier);
        if (update_method_vec_p)
! 	add_method (DECL_CONTEXT (clone), clone);
      }
    else
      {
--- 3835,3844 ----
  	 and a not-in-charge version.  */
        clone = build_clone (fn, complete_ctor_identifier);
        if (update_method_vec_p)
! 	add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
        clone = build_clone (fn, base_ctor_identifier);
        if (update_method_vec_p)
! 	add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
      }
    else
      {
*************** clone_function_decl (tree fn, int update
*** 3851,3864 ****
  	{
  	  clone = build_clone (fn, deleting_dtor_identifier);
  	  if (update_method_vec_p)
! 	    add_method (DECL_CONTEXT (clone), clone);
  	}
        clone = build_clone (fn, complete_dtor_identifier);
        if (update_method_vec_p)
! 	add_method (DECL_CONTEXT (clone), clone);
        clone = build_clone (fn, base_dtor_identifier);
        if (update_method_vec_p)
! 	add_method (DECL_CONTEXT (clone), clone);
      }
  
    /* Note that this is an abstract function that is never emitted.  */
--- 3857,3870 ----
  	{
  	  clone = build_clone (fn, deleting_dtor_identifier);
  	  if (update_method_vec_p)
! 	    add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
  	}
        clone = build_clone (fn, complete_dtor_identifier);
        if (update_method_vec_p)
! 	add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
        clone = build_clone (fn, base_dtor_identifier);
        if (update_method_vec_p)
! 	add_method (DECL_CONTEXT (clone), clone, NULL_TREE);
      }
  
    /* Note that this is an abstract function that is never emitted.  */
Index: cp/cp-tree.def
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.def,v
retrieving revision 1.94.4.2
diff -c -3 -p -r1.94.4.2 cp-tree.def
*** cp/cp-tree.def	8 Apr 2005 19:36:00 -0000	1.94.4.2
--- cp/cp-tree.def	12 Jul 2005 11:12:59 -0000
*************** DEFTREECODE (USING_DECL, "using_decl", t
*** 206,212 ****
  /* A using directive. The operand is USING_STMT_NAMESPACE.  */     
  DEFTREECODE (USING_STMT, "using_directive", tcc_expression, 1)
  
! /* An un-parsed default argument.  Looks like an IDENTIFIER_NODE.  */
  DEFTREECODE (DEFAULT_ARG, "default_arg", tcc_exceptional, 0)
  
  /* A template-id, like foo<int>.  The first operand is the template.
--- 206,214 ----
  /* A using directive. The operand is USING_STMT_NAMESPACE.  */     
  DEFTREECODE (USING_STMT, "using_directive", tcc_expression, 1)
  
! /* An un-parsed default argument.  Looks like an IDENTIFIER_NODE.
!    TREE_CHAIN is used to hold instantiations of functions that had to
!    be instantiated before the argument was parsed.  */
  DEFTREECODE (DEFAULT_ARG, "default_arg", tcc_exceptional, 0)
  
  /* A template-id, like foo<int>.  The first operand is the template.
Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1106.2.8
diff -c -3 -p -r1.1106.2.8 cp-tree.h
*** cp/cp-tree.h	5 Jun 2005 16:46:53 -0000	1.1106.2.8
--- cp/cp-tree.h	12 Jul 2005 11:13:03 -0000
*************** extern tree build_vfn_ref			(tree, tree)
*** 3693,3699 ****
  extern tree get_vtable_decl                     (tree, int);
  extern void resort_type_method_vec
    (void *, void *, gt_pointer_operator, void *);
! extern void add_method				(tree, tree);
  extern int currently_open_class			(tree);
  extern tree currently_open_derived_class	(tree);
  extern tree finish_struct			(tree, tree);
--- 3693,3699 ----
  extern tree get_vtable_decl                     (tree, int);
  extern void resort_type_method_vec
    (void *, void *, gt_pointer_operator, void *);
! extern void add_method				(tree, tree, tree);
  extern int currently_open_class			(tree);
  extern tree currently_open_derived_class	(tree);
  extern tree finish_struct			(tree, tree);
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1371.2.14
diff -c -3 -p -r1.1371.2.14 decl.c
*** cp/decl.c	3 Jun 2005 16:18:26 -0000	1.1371.2.14
--- cp/decl.c	12 Jul 2005 11:13:10 -0000
*************** cp_finish_decl (tree decl, tree init, tr
*** 4833,4838 ****
--- 4833,4848 ----
  		     "initialized", decl);
  	      init = NULL_TREE;
  	    }
+ 	  if (DECL_EXTERNAL (decl) && init)
+ 	    {
+ 	      /* The static data member cannot be initialized by a
+ 		 non-constant when being declared.  */
+ 	      error ("%qD cannot be initialized by a non-constant expression"
+ 		     " when being declared", decl);
+ 	      DECL_INITIALIZED_IN_CLASS_P (decl) = 0;
+ 	      init = NULL_TREE;
+ 	    }
+ 	  
  	  /* Handle:
  
  	     [dcl.init]
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.770.2.2
diff -c -3 -p -r1.770.2.2 decl2.c
*** cp/decl2.c	2 Jun 2005 17:31:01 -0000	1.770.2.2
--- cp/decl2.c	12 Jul 2005 11:13:12 -0000
*************** check_classfn (tree ctype, tree function
*** 717,723 ****
       case we'll only confuse ourselves when the function is declared
       properly within the class.  */
    if (COMPLETE_TYPE_P (ctype))
!     add_method (ctype, function);
    return NULL_TREE;
  }
  
--- 717,723 ----
       case we'll only confuse ourselves when the function is declared
       properly within the class.  */
    if (COMPLETE_TYPE_P (ctype))
!     add_method (ctype, function, NULL_TREE);
    return NULL_TREE;
  }
  
Index: cp/error.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/error.c,v
retrieving revision 1.279.2.1
diff -c -3 -p -r1.279.2.1 error.c
*** cp/error.c	6 Jun 2005 19:20:49 -0000	1.279.2.1
--- cp/error.c	12 Jul 2005 11:13:13 -0000
*************** dump_expr (tree t, int flags)
*** 1489,1495 ****
  	  {
  	    ob = TREE_OPERAND (ob, 0);
  	    if (TREE_CODE (ob) != PARM_DECL
! 		|| strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this"))
  	      {
  		dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
  		pp_cxx_arrow (cxx_pp);
--- 1489,1496 ----
  	  {
  	    ob = TREE_OPERAND (ob, 0);
  	    if (TREE_CODE (ob) != PARM_DECL
! 		|| (DECL_NAME (ob)
! 		    && strcmp (IDENTIFIER_POINTER (DECL_NAME (ob)), "this")))
  	      {
  		dump_expr (ob, flags | TFF_EXPR_IN_PARENS);
  		pp_cxx_arrow (cxx_pp);
Index: cp/method.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/method.c,v
retrieving revision 1.322.4.4
diff -c -3 -p -r1.322.4.4 method.c
*** cp/method.c	2 Jun 2005 17:57:10 -0000	1.322.4.4
--- cp/method.c	12 Jul 2005 11:13:14 -0000
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 471,480 ****
  	finish_expr_stmt (t);
        else
  	{
- 	  t = force_target_expr (TREE_TYPE (t), t);
  	  if (!this_adjusting)
! 	    t = thunk_adjust (t, /*this_adjusting=*/0,
! 			      fixed_offset, virtual_offset);
  	  finish_return_stmt (t);
  	}
  
--- 471,497 ----
  	finish_expr_stmt (t);
        else
  	{
  	  if (!this_adjusting)
! 	    {
! 	      tree cond = NULL_TREE;
! 
! 	      if (TREE_CODE (TREE_TYPE (t)) == POINTER_TYPE)
! 		{
! 		  /* If the return type is a pointer, we need to
! 		     protect against NULL.  We know there will be an
! 		     adjustment, because that's why we're emitting a
! 		     thunk.  */
! 		  t = save_expr (t);
! 		  cond = cp_convert (boolean_type_node, t);
! 		}
! 	      
! 	      t = thunk_adjust (t, /*this_adjusting=*/0,
! 				fixed_offset, virtual_offset);
! 	      if (cond)
! 		t = build3 (COND_EXPR, TREE_TYPE (t), cond, t,
! 			    cp_convert (TREE_TYPE (t), integer_zero_node));
! 	    }
! 	  t = force_target_expr (TREE_TYPE (t), t);
  	  finish_return_stmt (t);
  	}
  
*************** lazily_declare_fn (special_function_kind
*** 1090,1096 ****
    if (sfk == sfk_destructor)
      check_for_override (fn, type);
    /* Add it to CLASSTYPE_METHOD_VEC.  */
!   add_method (type, fn);
    /* Add it to TYPE_METHODS.  */
    if (sfk == sfk_destructor 
        && DECL_VIRTUAL_P (fn)
--- 1107,1113 ----
    if (sfk == sfk_destructor)
      check_for_override (fn, type);
    /* Add it to CLASSTYPE_METHOD_VEC.  */
!   add_method (type, fn, NULL_TREE);
    /* Add it to TYPE_METHODS.  */
    if (sfk == sfk_destructor 
        && DECL_VIRTUAL_P (fn)
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.319.2.9
diff -c -3 -p -r1.319.2.9 parser.c
*** cp/parser.c	5 Jun 2005 16:46:54 -0000	1.319.2.9
--- cp/parser.c	12 Jul 2005 11:13:23 -0000
*************** typedef struct cp_parser GTY(())
*** 1195,1201 ****
    /* The scope in which names should be looked up.  If NULL_TREE, then
       we look up names in the scope that is currently open in the
       source program.  If non-NULL, this is either a TYPE or
!      NAMESPACE_DECL for the scope in which we should look.
  
       This value is not cleared automatically after a name is looked
       up, so we must be careful to clear it before starting a new look
--- 1195,1202 ----
    /* The scope in which names should be looked up.  If NULL_TREE, then
       we look up names in the scope that is currently open in the
       source program.  If non-NULL, this is either a TYPE or
!      NAMESPACE_DECL for the scope in which we should look.  It can
!      also be ERROR_MARK, when we've parsed a bogus scope.
  
       This value is not cleared automatically after a name is looked
       up, so we must be careful to clear it before starting a new look
*************** typedef struct cp_parser GTY(())
*** 1203,1209 ****
       will look up `Z' in the scope of `X', rather than the current
       scope.)  Unfortunately, it is difficult to tell when name lookup
       is complete, because we sometimes peek at a token, look it up,
!      and then decide not to consume it.  */
    tree scope;
  
    /* OBJECT_SCOPE and QUALIFYING_SCOPE give the scopes in which the
--- 1204,1210 ----
       will look up `Z' in the scope of `X', rather than the current
       scope.)  Unfortunately, it is difficult to tell when name lookup
       is complete, because we sometimes peek at a token, look it up,
!      and then decide not to consume it.   */
    tree scope;
  
    /* OBJECT_SCOPE and QUALIFYING_SCOPE give the scopes in which the
*************** cp_parser_diagnose_invalid_type_name (cp
*** 1994,2000 ****
    if (TREE_CODE (decl) == TEMPLATE_DECL)
      error ("invalid use of template-name %qE without an argument list",
        decl);
!   else if (!parser->scope)
      {
        /* Issue an error message.  */
        error ("%qE does not name a type", id);
--- 1995,2001 ----
    if (TREE_CODE (decl) == TEMPLATE_DECL)
      error ("invalid use of template-name %qE without an argument list",
        decl);
!   else if (!parser->scope || parser->scope == error_mark_node)
      {
        /* Issue an error message.  */
        error ("%qE does not name a type", id);
*************** cp_parser_consume_semicolon_at_end_of_st
*** 2262,2297 ****
  static void
  cp_parser_skip_to_end_of_block_or_statement (cp_parser* parser)
  {
!   unsigned nesting_depth = 0;
  
!   while (true)
      {
!       cp_token *token;
! 
!       /* Peek at the next token.  */
!       token = cp_lexer_peek_token (parser->lexer);
!       /* If we've run out of tokens, stop.  */
        if (token->type == CPP_EOF)
  	break;
!       /* If the next token is a `;', we have reached the end of the
! 	 statement.  */
!       if (token->type == CPP_SEMICOLON && !nesting_depth)
  	{
! 	  /* Consume the `;'.  */
! 	  cp_lexer_consume_token (parser->lexer);
  	  break;
  	}
        /* Consume the token.  */
!       token = cp_lexer_consume_token (parser->lexer);
!       /* If the next token is a non-nested `}', then we have reached
! 	 the end of the current block.  */
!       if (token->type == CPP_CLOSE_BRACE
! 	  && (nesting_depth == 0 || --nesting_depth == 0))
! 	break;
!       /* If it the next token is a `{', then we are entering a new
! 	 block.  Consume the entire block.  */
!       if (token->type == CPP_OPEN_BRACE)
! 	++nesting_depth;
      }
  }
  
--- 2263,2310 ----
  static void
  cp_parser_skip_to_end_of_block_or_statement (cp_parser* parser)
  {
!   int nesting_depth = 0;
  
!   while (nesting_depth >= 0)
      {
!       cp_token *token = cp_lexer_peek_token (parser->lexer);
!       
        if (token->type == CPP_EOF)
  	break;
! 
!       switch (token->type)
  	{
! 	case CPP_EOF:
! 	  /* If we've run out of tokens, stop.  */
! 	  nesting_depth = -1;
! 	  continue;
! 
! 	case CPP_SEMICOLON:
! 	  /* Stop if this is an unnested ';'. */
! 	  if (!nesting_depth)
! 	    nesting_depth = -1;
! 	  break;
! 
! 	case CPP_CLOSE_BRACE:
! 	  /* Stop if this is an unnested '}', or closes the outermost
! 	     nesting level.  */
! 	  nesting_depth--;
! 	  if (!nesting_depth)
! 	    nesting_depth = -1;
! 	  break;
! 	  
! 	case CPP_OPEN_BRACE:
! 	  /* Nest. */
! 	  nesting_depth++;
! 	  break;
! 
! 	default:
  	  break;
  	}
+       
        /* Consume the token.  */
!       cp_lexer_consume_token (parser->lexer);
!       
      }
  }
  
*************** cp_parser_nested_name_specifier_opt (cp_
*** 3592,3600 ****
  /* Parse a nested-name-specifier.  See
     cp_parser_nested_name_specifier_opt for details.  This function
     behaves identically, except that it will an issue an error if no
!    nested-name-specifier is present, and it will return
!    ERROR_MARK_NODE, rather than NULL_TREE, if no nested-name-specifier
!    is present.  */
  
  static tree
  cp_parser_nested_name_specifier (cp_parser *parser,
--- 3605,3611 ----
  /* Parse a nested-name-specifier.  See
     cp_parser_nested_name_specifier_opt for details.  This function
     behaves identically, except that it will an issue an error if no
!    nested-name-specifier is present.  */
  
  static tree
  cp_parser_nested_name_specifier (cp_parser *parser,
*************** cp_parser_nested_name_specifier (cp_pars
*** 3616,3622 ****
      {
        cp_parser_error (parser, "expected nested-name-specifier");
        parser->scope = NULL_TREE;
-       return error_mark_node;
      }
  
    return scope;
--- 3627,3632 ----
*************** cp_parser_postfix_expression (cp_parser 
*** 3901,3907 ****
  	  id = cp_parser_identifier (parser);
  
  	/* Don't process id if nested name specifier is invalid.  */
! 	if (scope == error_mark_node)
  	  return error_mark_node;
  	/* If we look up a template-id in a non-dependent qualifying
  	   scope, there's no need to create a dependent type.  */
--- 3911,3917 ----
  	  id = cp_parser_identifier (parser);
  
  	/* Don't process id if nested name specifier is invalid.  */
! 	if (!scope || scope == error_mark_node)
  	  return error_mark_node;
  	/* If we look up a template-id in a non-dependent qualifying
  	   scope, there's no need to create a dependent type.  */
*************** cp_parser_elaborated_type_specifier (cp_
*** 9757,9768 ****
    /* Look for the nested-name-specifier.  */
    if (tag_type == typename_type)
      {
!       if (cp_parser_nested_name_specifier (parser,
  					   /*typename_keyword_p=*/true,
  					   /*check_dependency_p=*/true,
  					   /*type_p=*/true,
! 					   is_declaration)
! 	  == error_mark_node)
  	return error_mark_node;
      }
    else
--- 9767,9777 ----
    /* Look for the nested-name-specifier.  */
    if (tag_type == typename_type)
      {
!       if (!cp_parser_nested_name_specifier (parser,
  					   /*typename_keyword_p=*/true,
  					   /*check_dependency_p=*/true,
  					   /*type_p=*/true,
! 					    is_declaration))
  	return error_mark_node;
      }
    else
*************** cp_parser_late_parsing_default_args (cp_
*** 15457,15475 ****
         parm = TREE_CHAIN (parm))
      {
        cp_token_cache *tokens;
  
!       if (!TREE_PURPOSE (parm)
! 	  || TREE_CODE (TREE_PURPOSE (parm)) != DEFAULT_ARG)
  	continue;
  
!        /* Push the saved tokens for the default argument onto the parser's
! 	  lexer stack.  */
!       tokens = DEFARG_TOKENS (TREE_PURPOSE (parm));
        cp_parser_push_lexer_for_tokens (parser, tokens);
  
        /* Parse the assignment-expression.  */
!       TREE_PURPOSE (parm) = cp_parser_assignment_expression (parser,
! 							     /*cast_p=*/false);
  
        /* If the token stream has not been completely used up, then
  	 there was extra junk after the end of the default
--- 15466,15497 ----
         parm = TREE_CHAIN (parm))
      {
        cp_token_cache *tokens;
+       tree default_arg = TREE_PURPOSE (parm);
+       tree parsed_arg;
+       
+       if (!default_arg)
+ 	continue;
  
!       if (TREE_CODE (default_arg) != DEFAULT_ARG)
! 	/* This can happen for a friend declaration for a function
! 	   already declared with default arguments.  */
  	continue;
  
!       /* Push the saved tokens for the default argument onto the parser's
! 	 lexer stack.  */
!       tokens = DEFARG_TOKENS (default_arg);
        cp_parser_push_lexer_for_tokens (parser, tokens);
  
        /* Parse the assignment-expression.  */
!       parsed_arg = cp_parser_assignment_expression (parser, /*cast_p=*/false);
! 
!       TREE_PURPOSE (parm) = parsed_arg;
! 
!       /* Update any instantiations we've already created.  */
!       for (default_arg = TREE_CHAIN (default_arg);
! 	   default_arg;
! 	   default_arg = TREE_CHAIN (default_arg))
! 	TREE_PURPOSE (TREE_PURPOSE (default_arg)) = parsed_arg;
  
        /* If the token stream has not been completely used up, then
  	 there was extra junk after the end of the default
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.978.2.12
diff -c -3 -p -r1.978.2.12 pt.c
*** cp/pt.c	3 Jun 2005 16:18:30 -0000	1.978.2.12
--- cp/pt.c	12 Jul 2005 11:13:32 -0000
*************** tsubst_arg_types (tree arg_types, 
*** 6680,6685 ****
--- 6680,6687 ----
  {
    tree remaining_arg_types;
    tree type;
+   tree default_arg;
+   tree result = NULL_TREE;
  
    if (!arg_types || arg_types == void_list_node)
      return arg_types;
*************** tsubst_arg_types (tree arg_types, 
*** 6707,6718 ****
       top-level qualifiers as required.  */
    type = TYPE_MAIN_VARIANT (type_decays_to (type));
  
!   /* Note that we do not substitute into default arguments here.  The
!      standard mandates that they be instantiated only when needed,
!      which is done in build_over_call.  */
!   return hash_tree_cons (TREE_PURPOSE (arg_types), type,
! 			 remaining_arg_types);
! 			 
  }
  
  /* Substitute into a FUNCTION_TYPE or METHOD_TYPE.  This routine does
--- 6709,6733 ----
       top-level qualifiers as required.  */
    type = TYPE_MAIN_VARIANT (type_decays_to (type));
  
!   /* We do not substitute into default arguments here.  The standard
!      mandates that they be instantiated only when needed, which is
!      done in build_over_call.  */
!   default_arg = TREE_PURPOSE (arg_types);
!   
!   if (default_arg && TREE_CODE (default_arg) == DEFAULT_ARG)
!     {
!       /* We've instantiated a template before its default arguments
!  	 have been parsed.  This can happen for a nested template
!  	 class, and is not an error unless we require the default
!  	 argument in a call of this function.  */
!       result = tree_cons (default_arg, type, remaining_arg_types);
!       TREE_CHAIN (default_arg) = tree_cons (result, NULL_TREE,
! 					    TREE_CHAIN (default_arg));
!     }
!   else
!     result = hash_tree_cons (default_arg, type, remaining_arg_types);
!   
!   return result;
  }
  
  /* Substitute into a FUNCTION_TYPE or METHOD_TYPE.  This routine does
Index: cp/semantics.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/semantics.c,v
retrieving revision 1.463.2.4
diff -c -3 -p -r1.463.2.4 semantics.c
*** cp/semantics.c	25 May 2005 09:50:22 -0000	1.463.2.4
--- cp/semantics.c	12 Jul 2005 11:13:33 -0000
*************** finish_member_declaration (tree decl)
*** 2213,2219 ****
      {
        /* We also need to add this function to the
  	 CLASSTYPE_METHOD_VEC.  */
!       add_method (current_class_type, decl);
  
        TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
        TYPE_METHODS (current_class_type) = decl;
--- 2213,2219 ----
      {
        /* We also need to add this function to the
  	 CLASSTYPE_METHOD_VEC.  */
!       add_method (current_class_type, decl, NULL_TREE);
  
        TREE_CHAIN (decl) = TYPE_METHODS (current_class_type);
        TYPE_METHODS (current_class_type) = decl;
Index: testsuite/ChangeLog
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/ChangeLog,v
retrieving revision 1.5084.2.249
diff -c -3 -p -r1.5084.2.249 ChangeLog
*** testsuite/ChangeLog	7 Jul 2005 18:39:29 -0000	1.5084.2.249
--- testsuite/ChangeLog	12 Jul 2005 11:13:47 -0000
***************
*** 1,3 ****
--- 1,20 ----
+ 2005-07-11  Nathan Sidwell  <nathan@codesourcery.com>
+ 
+ 	PR c++/20678
+ 	* g++.dg/other/crash-4.C: New.
+ 
+ 	PR 21903
+ 	* g++.dg/parse/defarg9.C: New.
+ 
+ 	PR c++/21929
+ 	* g++.dg/parse/crash26.C: New.
+ 	
+ 	PR c++/20789
+ 	* g++.dg/init/member1.C: New.
+ 
+ 	PR c++/20746
+ 	* g++.dg/abi/covariant5.C: New.
+ 
  2005-07-07  Release Manager
  
  	* GCC 4.0.1 released.
Index: testsuite/g++.dg/abi/covariant5.C
===================================================================
RCS file: testsuite/g++.dg/abi/covariant5.C
diff -N testsuite/g++.dg/abi/covariant5.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/abi/covariant5.C	12 Jul 2005 11:13:49 -0000
***************
*** 0 ****
--- 1,52 ----
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 4 Apr 2005 <nathan@codesourcery.com>
+ 
+ // { dg-do run }
+ 
+ // PR 20746: Covariant return pointer could be null.
+ 
+ // Origin: yanliu@ca.ibm.com
+ //         nathan@codesourcery.com
+ 
+ struct A {
+   virtual void One ();
+ };
+ struct B  { 
+   virtual B *Two ();
+   virtual B &Three ();
+ };
+ 
+ struct C : A, B
+ {
+   virtual C *Two (); 
+   virtual C &Three (); 
+ };
+ void A::One () {}
+ B *B::Two()    {return this;}
+ B &B::Three()    {return *this;}
+ C *C::Two ()   {return 0;}
+ C &C::Three ()   {return *(C *)0;}
+ 
+ B *Foo (B *b)
+ {
+   return b->Two ();
+ }
+ 
+ B &Bar (B *b)
+ {
+   return b->Three ();
+ }
+ 
+ int main ()
+ {
+   C c;
+ 
+   /* We should not adjust a null pointer.  */
+   if (Foo (&c))
+     return 1;
+   /* But we should adjust a (bogus) null reference.  */
+   if (!&Bar (&c))
+     return 2;
+ 
+   return 0;
+ }
Index: testsuite/g++.dg/init/member1.C
===================================================================
RCS file: testsuite/g++.dg/init/member1.C
diff -N testsuite/g++.dg/init/member1.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/init/member1.C	12 Jul 2005 11:13:50 -0000
***************
*** 0 ****
--- 1,18 ----
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 13 Jun 2005 <nathan@codesourcery.com>
+ 
+ // Origin:   Ivan Godard <igodard@pacbell.net>
+ // Bug 20789: ICE on invalid
+ 
+ template<typename> struct A;
+ 
+ template<int> struct B {};
+ 
+ template<typename T> struct C
+ {
+   static const int i = A<T>::i;  // { dg-error "incomplete" }
+   static const int j = i;      // { dg-error "initialized by a non-const" }
+   B<j> b;  // { dg-error "not a valid template arg" }
+ };
+ 
+ C<int> c;
Index: testsuite/g++.dg/other/crash-4.C
===================================================================
RCS file: testsuite/g++.dg/other/crash-4.C
diff -N testsuite/g++.dg/other/crash-4.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/other/crash-4.C	12 Jul 2005 11:13:50 -0000
***************
*** 0 ****
--- 1,19 ----
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 14 Jun 2005 <nathan@codesourcery.com>
+ 
+ // PR 20678: ICE on error message
+ // Origin:  Andrew Pinski pinskia@gcc.gnu.org
+ 
+ struct a
+ {
+   a(const a&);
+ };
+ struct b
+ { // { dg-error "cannot bind packed field" }
+   a aa __attribute__((packed));
+ };
+ struct c
+ {
+   b bb;
+   c(const b& __a): bb(__a) {} // { dg-error "synthesized" }
+ };
Index: testsuite/g++.dg/overload/error1.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/overload/error1.C,v
retrieving revision 1.2
diff -c -3 -p -r1.2 error1.C
*** testsuite/g++.dg/overload/error1.C	11 Jul 2002 22:34:57 -0000	1.2
--- testsuite/g++.dg/overload/error1.C	12 Jul 2005 11:13:50 -0000
***************
*** 2,7 ****
  
  struct S
  {
!   void f () {}
!   int f () { return 0; } // { dg-error "" "" }
  };
--- 2,7 ----
  
  struct S
  {
!   void f () {} // { dg-error "with" "" }
!   int f () { return 0; } // { dg-error "overloaded" "" }
  };
Index: testsuite/g++.dg/parse/crash11.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.dg/parse/crash11.C,v
retrieving revision 1.4
diff -c -3 -p -r1.4 crash11.C
*** testsuite/g++.dg/parse/crash11.C	23 Sep 2004 21:27:17 -0000	1.4
--- testsuite/g++.dg/parse/crash11.C	12 Jul 2005 11:13:50 -0000
*************** struct B
*** 20,26 ****
    struct Template
    {
      typedef typename A<A<TP>::Template>  // { dg-error "mismatch|class template" }
!       ::template Template<T>::Type Type; // { dg-error "unqualified-id" }
    };
  };
  template <typename T>
--- 20,26 ----
    struct Template
    {
      typedef typename A<A<TP>::Template>  // { dg-error "mismatch|class template" }
!       ::template Template<T>::Type Type; // { dg-error "" }
    };
  };
  template <typename T>
Index: testsuite/g++.dg/parse/crash26.C
===================================================================
RCS file: testsuite/g++.dg/parse/crash26.C
diff -N testsuite/g++.dg/parse/crash26.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/parse/crash26.C	12 Jul 2005 11:13:50 -0000
***************
*** 0 ****
--- 1,12 ----
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 13 Jun 2005 <nathan@codesourcery.com>
+ 
+ // Origin:  Volker Reichelt <reichelt@gcc.gnu.org>
+ // Bug 21929: ICE on invalid
+ 
+ template<int> struct A
+ {
+     struct B;
+ };
+ 
+ template<> struct A<void>::B {}; // { dg-error "mismatch|expected|name a type|extra" }
Index: testsuite/g++.dg/parse/defarg9.C
===================================================================
RCS file: testsuite/g++.dg/parse/defarg9.C
diff -N testsuite/g++.dg/parse/defarg9.C
*** /dev/null	1 Jan 1970 00:00:00 -0000
--- testsuite/g++.dg/parse/defarg9.C	12 Jul 2005 11:13:50 -0000
***************
*** 0 ****
--- 1,20 ----
+ // Copyright (C) 2005 Free Software Foundation, Inc.
+ // Contributed by Nathan Sidwell 6 Jun 2005 <nathan@codesourcery.com>
+ 
+ // PR 21903:Reject legal with default arg confusion
+ // Origin:  Wolfgang Bangerth <bangerth@dealii.org>
+ 
+ 
+ struct O { 
+   template<typename T> struct B { 
+     void set (T, bool=true); 
+   }; 
+   
+   struct D : public B<int> {}; 
+ }; 
+ 
+ void x () 
+ { 
+   O::D d; 
+   d.set(1); 
+ }
Index: testsuite/g++.old-deja/g++.benjamin/warn02.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.benjamin/warn02.C,v
retrieving revision 1.4
diff -c -3 -p -r1.4 warn02.C
*** testsuite/g++.old-deja/g++.benjamin/warn02.C	1 May 2003 02:02:33 -0000	1.4
--- testsuite/g++.old-deja/g++.benjamin/warn02.C	12 Jul 2005 11:13:51 -0000
*************** class C
*** 31,46 ****
  class D
  {
  public:
!   int foo2() {return b;}  
!   int foo2() {return b;}  // { dg-error "" } 
    int b;
  };
  
  class E
  {
  public:
!   int foo2(); 
!   int foo2(); // { dg-error "" } 
    int b;
  };
  
--- 31,46 ----
  class D
  {
  public:
!   int foo2() {return b;}  // { dg-error "with" } 
!   int foo2() {return b;}  // { dg-error "overloaded" } 
    int b;
  };
  
  class E
  {
  public:
!   int foo2(); // { dg-error "with" } 
!   int foo2(); // { dg-error "overloaded" } 
    int b;
  };
  
Index: testsuite/g++.old-deja/g++.brendan/arm2.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.brendan/arm2.C,v
retrieving revision 1.3
diff -c -3 -p -r1.3 arm2.C
*** testsuite/g++.old-deja/g++.brendan/arm2.C	1 May 2003 02:02:34 -0000	1.3
--- testsuite/g++.old-deja/g++.brendan/arm2.C	12 Jul 2005 11:13:51 -0000
***************
*** 8,19 ****
  
  class X {
  public:
!    int foo();
!   static int foo();	// error: redeclaration// { dg-error "" } .*
  };
  
  class Y {
  public:
!    static int foo();
!   int foo();		// error: redeclaration// { dg-error "" } .*
  };
--- 8,19 ----
  
  class X {
  public:
!   int foo();            // { dg-error "with" }
!   static int foo();	// error: redeclaration// { dg-error "overloaded" } .*
  };
  
  class Y {
  public:
!    static int foo();    // { dg-error "with" }
!   int foo();		// error: redeclaration// { dg-error "overloaded" } .*
  };
Index: testsuite/g++.old-deja/g++.other/redecl2.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.other/redecl2.C,v
retrieving revision 1.3
diff -c -3 -p -r1.3 redecl2.C
*** testsuite/g++.old-deja/g++.other/redecl2.C	1 May 2003 02:02:50 -0000	1.3
--- testsuite/g++.old-deja/g++.other/redecl2.C	12 Jul 2005 11:13:52 -0000
***************
*** 1,9 ****
  // { dg-do assemble  }
  
  struct S {
!   S(int);
!   S(int); // { dg-error "" } already declared
  
!   ~S();
!   ~S(); // { dg-error "" } already declared
  };
--- 1,9 ----
  // { dg-do assemble  }
  
  struct S {
!   S(int); // { dg-error "with" }
!   S(int); // { dg-error "overloaded" } already declared
  
!   ~S();// { dg-error "with" }
!   ~S(); // { dg-error "overloaded" } already declared
  };
Index: testsuite/g++.old-deja/g++.other/redecl4.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.other/redecl4.C,v
retrieving revision 1.2
diff -c -3 -p -r1.2 redecl4.C
*** testsuite/g++.old-deja/g++.other/redecl4.C	1 May 2003 02:02:50 -0000	1.2
--- testsuite/g++.old-deja/g++.other/redecl4.C	12 Jul 2005 11:13:52 -0000
***************
*** 1,7 ****
  // { dg-do assemble  }
  int main() {
    struct A {
!     void f();
!     void f();			// { dg-error "" } already declared
    };
  }
--- 1,7 ----
  // { dg-do assemble  }
  int main() {
    struct A {
!     void f();			// { dg-error "with" } already declared
!     void f();			// { dg-error "overloaded" } already declared
    };
  }
Index: testsuite/g++.old-deja/g++.pt/memtemp78.C
===================================================================
RCS file: /cvs/gcc/gcc/gcc/testsuite/g++.old-deja/g++.pt/memtemp78.C,v
retrieving revision 1.3
diff -c -3 -p -r1.3 memtemp78.C
*** testsuite/g++.old-deja/g++.pt/memtemp78.C	1 May 2003 02:02:55 -0000	1.3
--- testsuite/g++.old-deja/g++.pt/memtemp78.C	12 Jul 2005 11:13:52 -0000
*************** template struct B<int>;
*** 23,32 ****
  struct C 
  {
    template <class U>
!   void f() {}
  
    template <class U>
!   void f() {}  // { dg-error "" } redeclaration
  };
  
  
--- 23,32 ----
  struct C 
  {
    template <class U>
!   void f() {}  // { dg-error "with" } redeclaration
  
    template <class U>
!   void f() {}  // { dg-error "overloaded" } redeclaration
  };
  
  
*************** template struct D<int, double>;
*** 42,56 ****
  template <class T, class U>
  struct D2
  {
!   void f(T);
!   void f(U); // { dg-error "" } redeclaration 
  };
  
  template struct D2<int, int>; 
  
  struct E
  {
!   void f(); 
!   void f(); // { dg-error "" } redeclaration
  };
  
--- 42,56 ----
  template <class T, class U>
  struct D2
  {
!   void f(T); // { dg-error "with" } redeclaration 
!   void f(U); // { dg-error "overloaded" } redeclaration 
  };
  
  template struct D2<int, int>; 
  
  struct E
  {
!   void f();  // { dg-error "with" } redeclaration
!   void f(); // { dg-error "overloaded" } redeclaration
  };
  

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