A strang g++ bug.

Jason Merrill jason@cygnus.com
Fri Oct 10 08:51:00 GMT 1997


>>>>> H J Lu <hjl@lucon.org> writes:

> While doing "make check" in libstdc++ on egcs 971008, I got
> /home/work/gnu/src/egcs/libstdc++/testsuite/libstdc++.tests/../../tests/tstring.cc:154: undefined reference to `basic_string<char, string_char_traits<char> > & basic_string<char, string_char_traits<char> >::replace<int *>(char *, char *, int *, int *)'

This fixes that bug.  There's still the crash someone else reported, tho.

Thu Oct  9 12:08:21 1997  Jason Merrill  <jason@yorick.cygnus.com>

	* pt.c (tsubst): Fix thinko.
	(instantiate_decl): Really use the original template.

Index: pt.c
===================================================================
RCS file: /cvs/cvsfiles/devo/gcc/cp/pt.c,v
retrieving revision 1.255
retrieving revision 1.256
diff -c -r1.255 -r1.256
*** pt.c	1997/10/07 07:51:03	1.255
--- pt.c	1997/10/09 19:13:46	1.256
***************
*** 22,30 ****
  
  /* Known bugs or deficiencies include:
  
-      templates for class static data don't work (methods only),
-      duplicated method templates can crash the compiler,
-      interface/impl data is taken from file defining the template,
       all methods must be provided in header files; can't use a source
       file that contains only the method templates and "just win".  */
  
--- 22,27 ----
***************
*** 2203,2213 ****
  	DECL_TEMPLATE_INFO (tmpl) = build_tree_list (t, args);
  	new_decl = tsubst (decl, args, nargs, in_decl);
  	DECL_RESULT (tmpl) = new_decl;
- 	DECL_INITIAL (new_decl) = DECL_INITIAL (decl);
  	DECL_TI_TEMPLATE (new_decl) = tmpl;
  	TREE_TYPE (tmpl) = TREE_TYPE (new_decl);
  	DECL_TEMPLATE_INSTANTIATIONS (tmpl) = NULL_TREE;
! 	SET_DECL_IMPLICIT_INSTANTIATION (decl);
  
  	/* The template parameters for this new template are all the
  	   template parameters for the old template, except the
--- 2200,2209 ----
  	DECL_TEMPLATE_INFO (tmpl) = build_tree_list (t, args);
  	new_decl = tsubst (decl, args, nargs, in_decl);
  	DECL_RESULT (tmpl) = new_decl;
  	DECL_TI_TEMPLATE (new_decl) = tmpl;
  	TREE_TYPE (tmpl) = TREE_TYPE (new_decl);
  	DECL_TEMPLATE_INSTANTIATIONS (tmpl) = NULL_TREE;
! 	SET_DECL_IMPLICIT_INSTANTIATION (tmpl);
  
  	/* The template parameters for this new template are all the
  	   template parameters for the old template, except the
***************
*** 2344,2349 ****
--- 2340,2352 ----
  		   template parameters are still just template
  		   parameters; there are no corresponding subsitution
  		   arguments.  */
+ 		/* FIXME The messed up thing here is that we get here with
+ 		   full args and only one level of parms.  This is necessary
+ 		   because when we partially instantiate a member template,
+ 		   even though there's really only one level of parms left
+ 		   we re-use the parms from the original template, which
+ 		   have level 2.  When this is fixed we can remove the
+ 		   add_to_template_args from instantiate_template.  */
  		tree tparms = DECL_TEMPLATE_PARMS (tmpl);
  
  		while (tparms && TREE_CHAIN (tparms) != NULL_TREE)
***************
*** 3409,3416 ****
        for (specs = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
  	   specs != NULL_TREE;
  	   specs = TREE_CHAIN (specs))
! 	if (comp_template_args (TREE_PURPOSE(specs),
! 				targ_ptr))
  	  return TREE_VALUE (specs);
      }
  
--- 3412,3418 ----
        for (specs = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
  	   specs != NULL_TREE;
  	   specs = TREE_CHAIN (specs))
! 	if (comp_template_args (TREE_PURPOSE (specs), targ_ptr))
  	  return TREE_VALUE (specs);
      }
  
***************
*** 4401,4407 ****
    tree tmpl = TI_TEMPLATE (ti);
    tree args = TI_ARGS (ti);
    tree td;
!   tree pattern;
    tree save_ti;
    int nested = in_function_p ();
    int d_defined;
--- 4403,4409 ----
    tree tmpl = TI_TEMPLATE (ti);
    tree args = TI_ARGS (ti);
    tree td;
!   tree decl_pattern, code_pattern;
    tree save_ti;
    int nested = in_function_p ();
    int d_defined;
***************
*** 4409,4445 ****
    int line = lineno;
    char *file = input_filename;
  
!   while (DECL_TEMPLATE_INSTANTIATION (tmpl))
!     tmpl = DECL_TI_TEMPLATE (tmpl);
  
!   pattern = DECL_TEMPLATE_RESULT (tmpl);
  
    if (TREE_CODE (d) == FUNCTION_DECL)
      {
        d_defined = (DECL_INITIAL (d) != NULL_TREE);
!       pattern_defined = (DECL_INITIAL (pattern) != NULL_TREE);
      }
    else
      {
        d_defined = ! DECL_IN_AGGR_P (d);
!       pattern_defined = ! DECL_IN_AGGR_P (pattern);
      }
  
    if (d_defined)
      return d;
  
-   if (TREE_CODE (d) == FUNCTION_DECL) 
-     {
-       tree specs;
- 
-       /* Check to see if there is a matching specialization. */
-       for (specs = DECL_TEMPLATE_SPECIALIZATIONS (tmpl);
- 	   specs != NULL_TREE;
- 	   specs = TREE_CHAIN (specs))
- 	if (comp_template_args (TREE_PURPOSE (specs), args))
- 	  return TREE_VALUE (specs);
-     }
- 
    /* This needs to happen before any tsubsting.  */
    if (! push_tinst_level (d))
      return d;
--- 4411,4442 ----
    int line = lineno;
    char *file = input_filename;
  
!   if (DECL_TEMPLATE_SPECIALIZATION (d))
!     return d;
! 
!   for (td = tmpl; DECL_TEMPLATE_INSTANTIATION (td); )
!     td = DECL_TI_TEMPLATE (td);
  
!   /* In the case of a member template, decl_pattern is the partially
!      instantiated declaration (in the instantiated class), and code_pattern
!      is the original template definition.  */
!   decl_pattern = DECL_TEMPLATE_RESULT (tmpl);
!   code_pattern = DECL_TEMPLATE_RESULT (td);
  
    if (TREE_CODE (d) == FUNCTION_DECL)
      {
        d_defined = (DECL_INITIAL (d) != NULL_TREE);
!       pattern_defined = (DECL_INITIAL (code_pattern) != NULL_TREE);
      }
    else
      {
        d_defined = ! DECL_IN_AGGR_P (d);
!       pattern_defined = ! DECL_IN_AGGR_P (code_pattern);
      }
  
    if (d_defined)
      return d;
  
    /* This needs to happen before any tsubsting.  */
    if (! push_tinst_level (d))
      return d;
***************
*** 4451,4462 ****
    /* We need to set up DECL_INITIAL regardless of pattern_defined if the
       variable is a static const initialized in the class body.  */
    if (TREE_CODE (d) == VAR_DECL
!       && ! DECL_INITIAL (d) && DECL_INITIAL (pattern))
      {
        pushclass (DECL_CONTEXT (d), 2);
!       DECL_INITIAL (d) = tsubst_expr
! 	(DECL_INITIAL (pattern), args,
! 	 TREE_VEC_LENGTH (args), tmpl);
        popclass (1);
      }
  
--- 4448,4458 ----
    /* We need to set up DECL_INITIAL regardless of pattern_defined if the
       variable is a static const initialized in the class body.  */
    if (TREE_CODE (d) == VAR_DECL
!       && ! DECL_INITIAL (d) && DECL_INITIAL (code_pattern))
      {
        pushclass (DECL_CONTEXT (d), 2);
!       DECL_INITIAL (d) = tsubst_expr (DECL_INITIAL (code_pattern), args,
! 				      TREE_VEC_LENGTH (args), tmpl);
        popclass (1);
      }
  
***************
*** 4472,4484 ****
  	      if (interface_unknown)
  		warn_if_unknown_interface (d);
  	    }
! 	  else if (DECL_INTERFACE_KNOWN (pattern))
  	    {
  	      DECL_INTERFACE_KNOWN (d) = 1;
! 	      DECL_NOT_REALLY_EXTERN (d) = ! DECL_EXTERNAL (pattern);
  	    }
  	  else
! 	    warn_if_unknown_interface (pattern);
  	}
  
        if (at_eof)
--- 4468,4480 ----
  	      if (interface_unknown)
  		warn_if_unknown_interface (d);
  	    }
! 	  else if (DECL_INTERFACE_KNOWN (code_pattern))
  	    {
  	      DECL_INTERFACE_KNOWN (d) = 1;
! 	      DECL_NOT_REALLY_EXTERN (d) = ! DECL_EXTERNAL (code_pattern);
  	    }
  	  else
! 	    warn_if_unknown_interface (code_pattern);
  	}
  
        if (at_eof)
***************
*** 4503,4520 ****
    input_filename = DECL_SOURCE_FILE (d);
  
    /* Trick tsubst into giving us a new decl in case the template changed.  */
!   save_ti = DECL_TEMPLATE_INFO (pattern);
!   DECL_TEMPLATE_INFO (pattern) = NULL_TREE;
!   td = tsubst (pattern, args, TREE_VEC_LENGTH (args), tmpl);
!   DECL_TEMPLATE_INFO (pattern) = save_ti;
  
    /* And set up DECL_INITIAL, since tsubst doesn't.  */
    if (TREE_CODE (td) == VAR_DECL)
      {
        pushclass (DECL_CONTEXT (d), 2);
!       DECL_INITIAL (td) = tsubst_expr
! 	(DECL_INITIAL (pattern), args,
! 	 TREE_VEC_LENGTH (args), tmpl);
        popclass (1);
      }
  
--- 4499,4515 ----
    input_filename = DECL_SOURCE_FILE (d);
  
    /* Trick tsubst into giving us a new decl in case the template changed.  */
!   save_ti = DECL_TEMPLATE_INFO (decl_pattern);
!   DECL_TEMPLATE_INFO (decl_pattern) = NULL_TREE;
!   td = tsubst (decl_pattern, args, TREE_VEC_LENGTH (args), tmpl);
!   DECL_TEMPLATE_INFO (decl_pattern) = save_ti;
  
    /* And set up DECL_INITIAL, since tsubst doesn't.  */
    if (TREE_CODE (td) == VAR_DECL)
      {
        pushclass (DECL_CONTEXT (d), 2);
!       DECL_INITIAL (td) = tsubst_expr (DECL_INITIAL (code_pattern), args,
! 				       TREE_VEC_LENGTH (args), tmpl);
        popclass (1);
      }
  
***************
*** 4546,4552 ****
      }
    else if (TREE_CODE (d) == FUNCTION_DECL)
      {
!       tree t = DECL_SAVED_TREE (pattern);
  
        start_function (NULL_TREE, d, NULL_TREE, 1);
        store_parm_decls ();
--- 4541,4547 ----
      }
    else if (TREE_CODE (d) == FUNCTION_DECL)
      {
!       tree t = DECL_SAVED_TREE (code_pattern);
  
        start_function (NULL_TREE, d, NULL_TREE, 1);
        store_parm_decls ();



More information about the Gcc mailing list