diff options
Diffstat (limited to 'gcc')
| -rw-r--r-- | gcc/cp/cp-tree.h | 2 | ||||
| -rw-r--r-- | gcc/cp/decl.c | 12 | ||||
| -rw-r--r-- | gcc/cp/decl2.c | 32 | ||||
| -rw-r--r-- | gcc/cp/friend.c | 5 | ||||
| -rw-r--r-- | gcc/cp/pt.c | 4 | ||||
| -rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
| -rw-r--r-- | gcc/testsuite/g++.dg/template/member5.C | 32 | 
7 files changed, 78 insertions, 16 deletions
| diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index c3c7c868e25..37170e2ca71 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -3721,7 +3721,7 @@ extern void maybe_make_one_only	(tree);  extern void grokclassfn	(tree, tree, enum overload_flags, tree);  extern tree grok_array_decl (tree, tree);  extern tree delete_sanity (tree, tree, bool, int); -extern tree check_classfn (tree, tree, bool); +extern tree check_classfn (tree, tree, tree);  extern void check_member_template (tree);  extern tree grokfield (tree, tree, tree, tree, tree);  extern tree grokbitfield (tree, tree, tree); diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 1b788310ca3..17b625f668c 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -3727,8 +3727,10 @@ start_decl (tree declarator,        else  	{  	  tree field = check_classfn (context, decl, -				      processing_template_decl -				      > template_class_depth (context)); +				      (processing_template_decl +				       > template_class_depth (context)) +				      ? current_template_parms +				      : NULL_TREE);  	  if (field && duplicate_decls (decl, field))  	    decl = field;  	} @@ -5691,8 +5693,10 @@ grokfndecl (tree ctype,        tree old_decl;        old_decl = check_classfn (ctype, decl, -				processing_template_decl -				> template_class_depth (ctype)); +				(processing_template_decl +				 > template_class_depth (ctype)) +				? current_template_parms +				: NULL_TREE);        if (old_decl && TREE_CODE (old_decl) == TEMPLATE_DECL)  	/* Because grokfndecl is always supposed to return a diff --git a/gcc/cp/decl2.c b/gcc/cp/decl2.c index e094493f988..5730d369efc 100644 --- a/gcc/cp/decl2.c +++ b/gcc/cp/decl2.c @@ -612,15 +612,19 @@ check_java_method (tree method)  /* Sanity check: report error if this function FUNCTION is not     really a member of the class (CTYPE) it is supposed to belong to. -   CNAME is the same here as it is for grokclassfn above. -   TEMPLATE_HEADER_P is true when this declaration comes with a -   template header.  */ +   TEMPLATE_PARMS is used to specifiy the template parameters of a member +   template passed as FUNCTION_DECL. If the member template is passed as a  +   TEMPLATE_DECL, it can be NULL since the parameters can be extracted +   from the declaration. If the function is not a function template, it +   must be NULL. +   It returns the original declaration for the function, or NULL_TREE +   if no declaration was found (and an error was emitted).  */  tree -check_classfn (tree ctype, tree function, bool template_header_p) +check_classfn (tree ctype, tree function, tree template_parms)  {    int ix; -  int is_template; +  bool is_template;    if (DECL_USE_TEMPLATE (function)        && !(TREE_CODE (function) == TEMPLATE_DECL @@ -638,9 +642,20 @@ check_classfn (tree ctype, tree function, bool template_header_p)         find the method, but we don't complain.  */      return NULL_TREE; +  /* Basic sanity check: for a template function, the template parameters +     either were not passed, or they are the same of DECL_TEMPLATE_PARMS.  */ +  if (TREE_CODE (function) == TEMPLATE_DECL) +    { +      my_friendly_assert (!template_parms  +			  || comp_template_parms  +			      (template_parms,  +			       DECL_TEMPLATE_PARMS (function)), +			  20040303); +      template_parms = DECL_TEMPLATE_PARMS (function); +    } +    /* OK, is this a definition of a member template?  */ -  is_template = (TREE_CODE (function) == TEMPLATE_DECL -		 || template_header_p); +  is_template = (template_parms != NULL_TREE);    ix = lookup_fnfields_1 (complete_type (ctype),  			  DECL_CONSTRUCTOR_P (function) ? ctor_identifier : @@ -684,6 +699,9 @@ check_classfn (tree ctype, tree function, bool template_header_p)  	  if (same_type_p (TREE_TYPE (TREE_TYPE (function)),  			   TREE_TYPE (TREE_TYPE (fndecl)))  	      && compparms (p1, p2) +	      && (!is_template +		  || comp_template_parms (template_parms,  +					  DECL_TEMPLATE_PARMS (fndecl)))  	      && (DECL_TEMPLATE_SPECIALIZATION (function)  		  == DECL_TEMPLATE_SPECIALIZATION (fndecl))  	      && (!DECL_TEMPLATE_SPECIALIZATION (function) diff --git a/gcc/cp/friend.c b/gcc/cp/friend.c index c81bd934e0a..e55adaa8bc0 100644 --- a/gcc/cp/friend.c +++ b/gcc/cp/friend.c @@ -397,7 +397,10 @@ do_friend (tree ctype, tree declarator, tree decl,  	       validity of the declaration later.  */  	    decl = push_template_decl_real (decl, /*is_friend=*/1);  	  else -	    decl = check_classfn (ctype, decl, template_member_p); +	    decl = check_classfn (ctype, decl,  +				  template_member_p  +				  ? current_template_parms +				  : NULL_TREE);  	  if (template_member_p && decl && TREE_CODE (decl) == FUNCTION_DECL)  	    decl = DECL_TI_TEMPLATE (decl); diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 5d2c95ac155..96ee6875a56 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -5142,8 +5142,8 @@ tsubst_friend_function (tree decl, tree args)      {        /* Check to see that the declaration is really present, and,  	 possibly obtain an improved declaration.  */ -      tree fn = check_classfn (DECL_CONTEXT (new_friend), -			       new_friend, false); +      tree fn = check_classfn (DECL_CONTEXT (new_friend),  +			       new_friend, NULL_TREE);        if (fn)  	new_friend = fn; diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5735a6c5548..df01d26d23e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,6 +1,11 @@ +2004-05-03  Giovanni Bajo  <giovannibajo@gcc.gnu.org> + +	PR c++/14389 +	* g++.dg/template/member5.C: New test. +  2004-05-03  Uros Bizjak  <uros@kss-loka.si> -        * gcc.dg/builtins-34.c: Also check expm1*. +	* gcc.dg/builtins-34.c: Also check expm1*.  2004-05-01  Kaveh R. Ghazi  <ghazi@caip.rutgers.edu> diff --git a/gcc/testsuite/g++.dg/template/member5.C b/gcc/testsuite/g++.dg/template/member5.C new file mode 100644 index 00000000000..45dcd6c6c66 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/member5.C @@ -0,0 +1,32 @@ +// { dg-do compile } +// Contributed by: <fasbjx at free dot fr> +// PR c++/14389: Disambiguate overloaded member templates which differ only +//  in the template argument list. + +namespace N1 { + +struct S {  +    template< typename B, typename A > void foo();  +    template< typename A >             void foo();  +};  +  +template< typename A >             void S::foo() {}  +template< typename B, typename A > void S::foo() {}  +  +template void S::foo<void> ();  +template void S::foo<void,void> ();  + +} + +namespace N2 { + +struct S {  +  template< typename _A > void foo();  +  template< int _i >      void foo();  +};  + +template< typename _A > void S::foo() {}  + +template void S::foo< 0 >();    // { dg-error "no definition available|instantiated from here" } + +} | 

