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]

[C++ PATCH] Fix bug 1509


Hi,
I've installed this obvious patch for 1509 where we ICE'd on a non-type
template parm. We only checked nontype parms when declaring the template,
we'd not check the deduced T on something like
	template <typename T, T v> ....
I commonized that code.

built & tested on i686-pc-linux-gnu

nathan
-- 
Dr Nathan Sidwell   ::   http://www.codesourcery.com   ::   CodeSourcery LLC
         'But that's a lie.' - 'Yes it is. What's your point?'
nathan@codesourcery.com : http://www.cs.bris.ac.uk/~nathan/ : nathan@acm.org
2001-01-12  Nathan Sidwell  <nathan@codesourcery.com>

	* pt.c (check_nontype_parm): New function.
	(process_template_parm): Use it.
	(convert_template_argument): Use it.
	(convert_nontype_argument, RECORD_TYPE): Assert it's a ptr to
	member.

Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/cp/pt.c,v
retrieving revision 1.503
diff -c -3 -p -r1.503 pt.c
*** pt.c	2001/01/11 11:45:01	1.503
--- pt.c	2001/01/14 16:49:15
*************** static tree for_each_template_parm_r PAR
*** 169,174 ****
--- 169,175 ----
  static tree instantiate_clone PARAMS ((tree, tree));
  static tree copy_default_args_to_explicit_spec_1 PARAMS ((tree, tree));
  static void copy_default_args_to_explicit_spec PARAMS ((tree));
+ static int check_nontype_parm PARAMS ((tree, int));
  
  /* Called once to initialize pt.c.  */
  
*************** process_template_parm (list, next)
*** 1933,1953 ****
  
        /* A template parameter is not modifiable.  */
        TREE_READONLY (parm) = 1;
!       if (IS_AGGR_TYPE (TREE_TYPE (parm))
! 	  && TREE_CODE (TREE_TYPE (parm)) != TEMPLATE_TYPE_PARM
! 	  && TREE_CODE (TREE_TYPE (parm)) != TYPENAME_TYPE)
! 	{
! 	  cp_error ("`%#T' is not a valid type for a template constant parameter",
! 		    TREE_TYPE (parm));
! 	  if (DECL_NAME (parm) == NULL_TREE)
! 	    error ("  a template type parameter must begin with `class' or `typename'");
! 	  TREE_TYPE (parm) = void_type_node;
! 	}
!       else if (pedantic
! 	       && (TREE_CODE (TREE_TYPE (parm)) == REAL_TYPE
! 		   || TREE_CODE (TREE_TYPE (parm)) == COMPLEX_TYPE))
! 	cp_pedwarn ("`%T' is not a valid type for a template constant parameter",
! 		    TREE_TYPE (parm));
        decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
        DECL_INITIAL (parm) = DECL_INITIAL (decl) 
  	= build_template_parm_index (idx, processing_template_decl,
--- 1934,1941 ----
  
        /* A template parameter is not modifiable.  */
        TREE_READONLY (parm) = 1;
!       if (check_nontype_parm (TREE_TYPE (parm), 1))
!         TREE_TYPE (parm) = void_type_node;
        decl = build_decl (CONST_DECL, DECL_NAME (parm), TREE_TYPE (parm));
        DECL_INITIAL (parm) = DECL_INITIAL (decl) 
  	= build_template_parm_index (idx, processing_template_decl,
*************** convert_nontype_argument (type, expr)
*** 3134,3146 ****
  
      case RECORD_TYPE:
        {
! 	if (!TYPE_PTRMEMFUNC_P (type))
! 	  /* This handles templates like
! 	       template<class T, T t> void f();
! 	     when T is substituted with any class.  The second template
! 	     parameter becomes invalid and the template candidate is
! 	     rejected.  */
! 	  return error_mark_node;
  
  	/* For a non-type template-parameter of type pointer to member
  	   function, no conversions apply.  If the template-argument
--- 3124,3130 ----
  
      case RECORD_TYPE:
        {
! 	my_friendly_assert (TYPE_PTRMEMFUNC_P (type), 20010112);
  
  	/* For a non-type template-parameter of type pointer to member
  	   function, no conversions apply.  If the template-argument
*************** convert_template_argument (parm, arg, ar
*** 3435,3440 ****
--- 3419,3427 ----
      {
        tree t = tsubst (TREE_TYPE (parm), args, complain, in_decl);
  
+       if (check_nontype_parm (t, complain))
+         return error_mark_node;
+       
        if (processing_template_decl)
  	arg = maybe_fold_nontype_arg (arg);
  
*************** tree
*** 10315,10318 ****
--- 10302,10337 ----
  current_instantiation ()
  {
    return current_tinst_level;
+ }
+ 
+ /* [temp.param] Check that template non-type parm TYPE is of an allowable
+    type. Return zero for ok, non-zero for disallowed. If COMPLAIN is
+    non-zero, then complain. */
+ 
+ static int
+ check_nontype_parm (type, complain)
+      tree type;
+      int complain;
+ {
+   if (INTEGRAL_TYPE_P (type))
+     return 0;
+   else if (POINTER_TYPE_P (type))
+     return 0;
+   else if (TYPE_PTRMEM_P (type))
+     return 0;
+   else if (TYPE_PTRMEMFUNC_P (type))
+     return 0;
+   else if (!pedantic && TREE_CODE (type) == REAL_TYPE)
+     return 0; /* GNU extension */
+   else if (!pedantic && TREE_CODE (type) == COMPLEX_TYPE)
+     return 0; /* GNU extension */
+   else if (TREE_CODE (type) == TEMPLATE_TYPE_PARM)
+     return 0;
+   else if (TREE_CODE (type) == TYPENAME_TYPE)
+     return 0;
+            
+   if (complain)
+     cp_error ("`%#T' is not a valid type for a template constant parameter",
+               type);
+   return 1;
  }
// Build don't link:

// Copyright (C) 2000 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 10 Jan 2001 <nathan@codesourcery.com>

// Bug 1509. We ICE'd on trying to coerce a non-type template parm
// that wouldn't.

template<class T>
struct A {
typedef int F();
};

template<class T, A<T>::F f>
struct B {
static int g() { return f(); };
};

int f() { return 0; };

int main() {
return B<int,&f>::g();  // ERROR - could not convert arg
};

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