This is the mail archive of the gcc-bugs@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]

PATCH for Re: foo.cc:15: Internal compiler error.



> I've been playing around with template specialisation, the following
> code is likely wrong but in any case it causes an internal compiler error:

Here's a fix for your problem.  Your code is actually legal:

  template <class A*>
  void f();

is not a specialization, but a declares an (anonymous) non-type
parameter of type `class A*', and forward-declares `class A'.  Would
you believe it?

Jason, is this ok to check in?

-- 
Mark Mitchell 			mark@markmitchell.com
Mark Mitchell Consulting	http://www.markmitchell.com

1998-05-23  Mark Mitchell  <mark@markmitchell.com>

	* cp-tree.h (processing_template_parmlist): Declare.
	* decl.c (pushtag): Don't call push_template_decl when we
	shouldn't. 
	* pt.c (processing_template_parmlist): New variable.
	(TMPL_ARGS_HAVE_MULTIPLE_LEVELS): New macro.
	(complete_template_args): Use it.
	(add_to_template_args): Likewise.
	(innermost_args): Likewise.
	(tsubst): Likewise.
	(begin_template_parm_list): Use processing_template_parmlist.
	(end_template_parm_list): Likewise.
	
Index: cp-tree.h
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/cp-tree.h,v
retrieving revision 1.74
diff -c -p -r1.74 cp-tree.h
*** cp-tree.h	1998/05/23 02:18:29	1.74
--- cp-tree.h	1998/05/23 23:15:55
*************** extern int comp_template_args           
*** 2644,2649 ****
--- 2661,2667 ----
  
  extern int processing_specialization;
  extern int processing_explicit_instantiation;
+ extern int processing_template_parmlist;
  
  /* in repo.c */
  extern void repo_template_used			PROTO((tree));
Index: decl.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/decl.c,v
retrieving revision 1.117
diff -c -p -r1.117 decl.c
*** decl.c	1998/05/22 23:13:27	1.117
--- decl.c	1998/05/23 23:16:34
*************** pushtag (name, type, globalize)
*** 2291,2299 ****
  		         friend class S2; 
  		       };
  
! 		     declares S2 to be at global scope.  */
! 		  || (processing_template_decl > 
! 		      template_class_depth (current_class_type))))
  	    {
  	      d = push_template_decl_real (d, globalize);
  	      /* If the current binding level is the binding level for
--- 2291,2305 ----
  		         friend class S2; 
  		       };
  
! 		     declares S2 to be at global scope.  We must be
! 		     careful, however, of the following case:
! 
! 		       template <class A*> struct S;
! 
! 		     which declares a non-template class `A'.  */
! 		  || (!processing_template_parmlist
! 		      && (processing_template_decl > 
! 			  template_class_depth (current_class_type)))))
  	    {
  	      d = push_template_decl_real (d, globalize);
  	      /* If the current binding level is the binding level for
Index: pt.c
===================================================================
RCS file: /egcs/carton/cvsfiles/egcs/gcc/cp/pt.c,v
retrieving revision 1.143
diff -c -p -r1.143 pt.c
*** pt.c	1998/05/23 02:18:31	1.143
--- pt.c	1998/05/23 23:17:28
*************** int minimal_parse_mode;
*** 63,68 ****
--- 63,69 ----
  
  int processing_specialization;
  int processing_explicit_instantiation;
+ int processing_template_parmlist;
  static int template_header_count;
  
  static tree saved_trees;
*************** static int check_cv_quals_for_unify PROT
*** 115,120 ****
--- 116,129 ----
  static tree tsubst_template_arg_vector PROTO((tree, tree));
  static void regenerate_decl_from_template PROTO((tree, tree));
  
+ /* Nonzero if ARGVEC contains multiple levels of template arguments.  */
+ #define TMPL_ARGS_HAVE_MULTIPLE_LEVELS(NODE) 		\
+   (NODE != NULL_TREE 					\
+    && TREE_CODE (NODE) == TREE_VEC 			\
+    && TREE_VEC_LENGTH (NODE) > 0 			\
+    && TREE_VEC_ELT (NODE, 0) != NULL_TREE               \
+    && TREE_CODE (TREE_VEC_ELT (NODE, 0)) == TREE_VEC)
+ 
  /* Do any processing required when DECL (a member template declaration
     using TEMPLATE_PARAMETERS as its innermost parameter list) is
     finished.  Returns the TEMPLATE_DECL corresponding to DECL, unless
*************** complete_template_args (tmpl, extra_args
*** 388,394 ****
    my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0);
    my_friendly_assert (TREE_CODE (extra_args) == TREE_VEC, 0);
  
!   if (TREE_CODE (TREE_VEC_ELT (extra_args, 0)) == TREE_VEC)
      extra_arg_depth = TREE_VEC_LENGTH (extra_args);
    else
      extra_arg_depth = 1;
--- 397,403 ----
    my_friendly_assert (TREE_CODE (tmpl) == TEMPLATE_DECL, 0);
    my_friendly_assert (TREE_CODE (extra_args) == TREE_VEC, 0);
  
!   if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (extra_args))
      extra_arg_depth = TREE_VEC_LENGTH (extra_args);
    else
      extra_arg_depth = 1;
*************** complete_template_args (tmpl, extra_args
*** 411,417 ****
  	     TEMPLATE_DECL with DECL_TEMPLATE_INFO.  DECL_TI_ARGS is
  	     all the bound template arguments.  */
  	  args = DECL_TI_ARGS (tmpl);
! 	  if (TREE_CODE (TREE_VEC_ELT (args, 0)) != TREE_VEC)
  	    depth = 1;
  	  else
  	    depth = TREE_VEC_LENGTH (args);
--- 420,426 ----
  	     TEMPLATE_DECL with DECL_TEMPLATE_INFO.  DECL_TI_ARGS is
  	     all the bound template arguments.  */
  	  args = DECL_TI_ARGS (tmpl);
! 	  if (!TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
  	    depth = 1;
  	  else
  	    depth = TREE_VEC_LENGTH (args);
*************** add_to_template_args (args, extra_args)
*** 485,491 ****
  {
    tree new_args;
  
!   if (TREE_CODE (TREE_VEC_ELT (args, 0)) != TREE_VEC)
      {
        new_args = make_tree_vec (2);
        TREE_VEC_ELT (new_args, 0) = args;
--- 494,500 ----
  {
    tree new_args;
  
!   if (!TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
      {
        new_args = make_tree_vec (2);
        TREE_VEC_ELT (new_args, 0) = args;
*************** begin_template_parm_list ()
*** 529,534 ****
--- 538,544 ----
    pushlevel (0);
    declare_pseudo_global_level ();
    ++processing_template_decl;
+   ++processing_template_parmlist;
    note_template_header (0);
  }
  
*************** end_template_parm_list (parms)
*** 1452,1457 ****
--- 1462,1469 ----
    for (parm = parms, nparms = 0; parm; parm = TREE_CHAIN (parm), nparms++)
      TREE_VEC_ELT (saved_parmlist, nparms) = parm;
  
+   --processing_template_parmlist;
+ 
    return saved_parmlist;
  }
  
*************** innermost_args (args, is_spec)
*** 3993,3999 ****
       tree args;
       int is_spec;
  {
!   if (args != NULL_TREE && TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
      return TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1 - is_spec);
    return args;
  }
--- 4005,4011 ----
       tree args;
       int is_spec;
  {
!   if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
      return TREE_VEC_ELT (args, TREE_VEC_LENGTH (args) - 1 - is_spec);
    return args;
  }
*************** tsubst (t, args, in_decl)
*** 4189,4196 ****
  	  {
  	    tree arg = NULL_TREE;
  
! 	    if (TREE_VEC_ELT (args, 0) != NULL_TREE
! 		&& TREE_CODE (TREE_VEC_ELT (args, 0)) == TREE_VEC)
  	      {
  		levels = TREE_VEC_LENGTH (args);
  		if (level <= levels)
--- 4201,4207 ----
  	  {
  	    tree arg = NULL_TREE;
  
! 	    if (TMPL_ARGS_HAVE_MULTIPLE_LEVELS (args))
  	      {
  		levels = TREE_VEC_LENGTH (args);
  		if (level <= levels)

Index: spec18.C
===================================================================
RCS file: spec18.C
diff -N spec18.C
*** /dev/null	Mon Dec 31 20:00:00 1979
--- spec18.C	Sat May 23 16:34:25 1998
***************
*** 0 ****
--- 1,30 ----
+ // Build don't link:
+ 
+ template<class A, class B>
+ void foo(const A& a, const B& b)
+ {
+ }
+ 
+ template<class A, class B>
+ void foo(const A& a, const int& b)
+ {
+ }
+ 
+ template<class A*, class B>
+ void foo(const A*& a, const B& b)
+ {
+ }
+ 
+ template<>
+ void foo(const int&, const double&)
+ {
+ }
+ 
+ 
+ int
+ main()
+ {
+   foo("98239", 23);
+   foo(232, 1.022);
+ }
+ 


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