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]

[C++ PATCH,committed] Fix PR2513 (incorrect dependent logic inmake_typename_type)


Hi

The following patch fixes an incorrect logic whether a typename
should be treated as dependent name or not.  We current use
'uses_template_parms' inside 'make_typename_type' which fails
to handle case like

  template <class T> class A {
    class B { ... };
    typename B::X f(); // This should be dependent name
                       // according to DR108.
  };

The correct call there should be 'dependent_type_p' instead.
I correct the misuse in 'make_typename_type' together with its
counterpart 'make_unbound_class_template'.

Some missing 'processing_template_decl' increment/decrement are
caught after the changes.  Also pre-increment/decrement are used
throughout the frontend for ease of grep'ing.

Tested on i686-pc-linux-gnu.  Committed to trunk as obvious.

--Kriang


2003-10-17  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/2513
	* decl.c (make_typename_type): Use dependent_type_p.
	(make_unbound_class_template): Likewise.
	* pt.c (instantiate_class_template): Increment
	processing_template_decl during substitution of template friend
	function.  Preincrement processing_template_decl rather than
	postincrement.
	(get_mostly_instantiated_function_type): Increment
	processing_template_decl during partial substitution of function
	type.

2003-10-17  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/2513
	* g++.dg/template/typename5.C: New test.


diff -cprN gcc-main-save/gcc/cp/decl.c gcc-main-new/gcc/cp/decl.c
*** gcc-main-save/gcc/cp/decl.c	Fri Oct 17 09:16:26 2003
--- gcc-main-new/gcc/cp/decl.c	Fri Oct 17 15:56:28 2003
*************** make_typename_type (tree context, tree n
*** 2604,2610 ****
        return error_mark_node;
      }
  
!   if (! uses_template_parms (context)
        || currently_open_class (context))
      {
        if (TREE_CODE (fullname) == TEMPLATE_ID_EXPR)
--- 2604,2610 ----
        return error_mark_node;
      }
  
!   if (!dependent_type_p (context)
        || currently_open_class (context))
      {
        if (TREE_CODE (fullname) == TEMPLATE_ID_EXPR)
*************** make_typename_type (tree context, tree n
*** 2663,2669 ****
  
    /* If the CONTEXT is not a template type, then either the field is
       there now or its never going to be.  */
!   if (!uses_template_parms (context))
      {
        if (complain & tf_error)
  	error ("no type named `%#T' in `%#T'", name, context);
--- 2663,2669 ----
  
    /* If the CONTEXT is not a template type, then either the field is
       there now or its never going to be.  */
!   if (!dependent_type_p (context))
      {
        if (complain & tf_error)
  	error ("no type named `%#T' in `%#T'", name, context);
*************** make_unbound_class_template (tree contex
*** 2692,2698 ****
    if (TREE_CODE (name) != IDENTIFIER_NODE)
      abort ();
  
!   if (!uses_template_parms (context)
        || currently_open_class (context))
      {
        tree tmpl = NULL_TREE;
--- 2692,2698 ----
    if (TREE_CODE (name) != IDENTIFIER_NODE)
      abort ();
  
!   if (!dependent_type_p (context)
        || currently_open_class (context))
      {
        tree tmpl = NULL_TREE;
diff -cprN gcc-main-save/gcc/cp/pt.c gcc-main-new/gcc/cp/pt.c
*** gcc-main-save/gcc/cp/pt.c	Fri Oct 17 09:16:27 2003
--- gcc-main-new/gcc/cp/pt.c	Fri Oct 17 15:56:28 2003
*************** instantiate_class_template (tree type)
*** 5294,5303 ****
  	      tree r;
  	      
  	      if (TREE_CODE (t) == TEMPLATE_DECL)
! 		processing_template_decl++;
  	      r = tsubst (t, args, tf_error, NULL_TREE);
  	      if (TREE_CODE (t) == TEMPLATE_DECL)
! 		processing_template_decl--;
  	      set_current_access_from_decl (r);
  	      grok_special_member_properties (r);
  	      finish_member_declaration (r);
--- 5294,5303 ----
  	      tree r;
  	      
  	      if (TREE_CODE (t) == TEMPLATE_DECL)
! 		++processing_template_decl;
  	      r = tsubst (t, args, tf_error, NULL_TREE);
  	      if (TREE_CODE (t) == TEMPLATE_DECL)
! 		--processing_template_decl;
  	      set_current_access_from_decl (r);
  	      grok_special_member_properties (r);
  	      finish_member_declaration (r);
*************** instantiate_class_template (tree type)
*** 5317,5326 ****
  		  input_location = DECL_SOURCE_LOCATION (t);
  
  		  if (TREE_CODE (t) == TEMPLATE_DECL)
! 		    processing_template_decl++;
  		  r = tsubst (t, args, tf_error | tf_warning, NULL_TREE);
  		  if (TREE_CODE (t) == TEMPLATE_DECL)
! 		    processing_template_decl--;
  		  if (TREE_CODE (r) == VAR_DECL)
  		    {
  		      tree init;
--- 5317,5326 ----
  		  input_location = DECL_SOURCE_LOCATION (t);
  
  		  if (TREE_CODE (t) == TEMPLATE_DECL)
! 		    ++processing_template_decl;
  		  r = tsubst (t, args, tf_error | tf_warning, NULL_TREE);
  		  if (TREE_CODE (t) == TEMPLATE_DECL)
! 		    --processing_template_decl;
  		  if (TREE_CODE (r) == VAR_DECL)
  		    {
  		      tree init;
*************** instantiate_class_template (tree type)
*** 5412,5420 ****
  		--processing_template_decl;
  	    }
  	  else
! 	    /* Build new DECL_FRIENDLIST.  */
! 	    add_friend (type, tsubst_friend_function (t, args),
! 			/*complain=*/false);
  	}
      }
  
--- 5412,5428 ----
  		--processing_template_decl;
  	    }
  	  else
! 	    {
! 	      /* Build new DECL_FRIENDLIST.  */
! 	      tree r;
! 
! 	      if (TREE_CODE (t) == TEMPLATE_DECL)
! 		++processing_template_decl;
! 	      r = tsubst_friend_function (t, args);
! 	      if (TREE_CODE (t) == TEMPLATE_DECL)
! 		--processing_template_decl;
! 	      add_friend (type, r, /*complain=*/false);
! 	    }
  	}
      }
  
*************** get_mostly_instantiated_function_type (t
*** 11246,11254 ****
--- 11254,11264 ----
  	 specialized or not.  */
        push_access_scope (decl);
  
+       ++processing_template_decl;
        /* Now, do the (partial) substitution to figure out the
  	 appropriate function type.  */
        fn_type = tsubst (fn_type, partial_args, tf_error, NULL_TREE);
+       --processing_template_decl;
  
        /* Substitute into the template parameters to obtain the real
  	 innermost set of parameters.  This step is important if the
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/template/typename5.C gcc-main-new/gcc/testsuite/g++.dg/template/typename5.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/typename5.C	Thu Jan  1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/typename5.C	Fri Oct 17 19:25:59 2003
***************
*** 0 ****
--- 1,19 ----
+ // { dg-do compile }
+ 
+ // Origin: ariels@compugen.co.il
+ 
+ // PR c++/2513: typename handling when scope is dependent as
+ // described in DR108.
+ 
+ template <bool flag> struct Select {
+   typedef int Result;
+ };
+ 
+ template <template<class> class Pred> struct FindType {
+   typedef typename Select<true>::Result Result;
+ };
+ 
+ template <int bits> struct Int {
+   template<typename T> struct RightSize {};
+   typedef typename FindType<RightSize>::Result type;
+ };


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