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 for 3.3] Fix PR10849


Hi

My earlier fix to PR10849 (a regression in 3.3 only):

  http://gcc.gnu.org/ml/gcc-patches/2003-05/msg02152.html

still has problem with partial specialization.  This is reported in
the follow up to the bug in bugzilla.  So this patch removes the
previous workaround and provides the fix to the root of the problem.

With the patch, the parser now handles class head uniformly whether
the class head is a template-id or not.  When the class head is a 
nested name, we always enter its scope and the parser state 
'new_type_flag' is set correctly.  All this logic is placed inside 
the new 'handle_class_head_apparent_template' function.

Tested on i686-pc-linux-gnu.  OK for 3.3 branch?

--Kriang


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

	PR c++/10849
	* decl2.c (handle_class_head_apparent_template): New function.
	* cp-tree.h (handle_class_head_apparent_template): Add declaration.
	* parse.y (class_head_defn): Use it.
	* search.c (type_access_control): Revert my 2003-05-25 change.

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

	PR c++/10849
	* g++.dg/template/access12.C: New test.


diff -cprN gcc-33-save/gcc/cp/cp-tree.h gcc-33-new/gcc/cp/cp-tree.h
*** gcc-33-save/gcc/cp/cp-tree.h	Sun Jul  6 17:19:29 2003
--- gcc-33-new/gcc/cp/cp-tree.h	Mon Jul  7 20:44:02 2003
*************** extern void do_using_directive			PARAMS 
*** 3905,3910 ****
--- 3905,3911 ----
  extern void check_default_args			PARAMS ((tree));
  extern void mark_used				PARAMS ((tree));
  extern tree handle_class_head			(enum tag_types, tree, tree, tree, int, int *);
+ extern tree handle_class_head_apparent_template	(tree, int *);
  extern tree lookup_arg_dependent                PARAMS ((tree, tree, tree));
  extern void finish_static_data_member_decl      PARAMS ((tree, tree, tree, int));
  extern tree cp_build_parm_decl                  PARAMS ((tree, tree));
diff -cprN gcc-33-save/gcc/cp/decl2.c gcc-33-new/gcc/cp/decl2.c
*** gcc-33-save/gcc/cp/decl2.c	Sun Jul  6 17:19:29 2003
--- gcc-33-new/gcc/cp/decl2.c	Mon Jul  7 21:08:55 2003
*************** handle_class_head (tag_kind, scope, id, 
*** 5030,5033 ****
--- 5030,5080 ----
    return decl;
  }
  
+ /* Like handle_class_head but for a definition of a class specialization.
+    DECL is a TYPE_DECL node representing the class.  NEW_TYPE_P is set to
+    nonzero, if we push into the scope containing the to be defined
+    aggregate.
+ 
+    Return a TYPE_DECL for the type declared by ID in SCOPE.  */
+ 
+ tree
+ handle_class_head_apparent_template (decl, new_type_p)
+     tree decl;
+     int *new_type_p;
+ {
+   tree context;
+   tree current;
+ 
+   if (decl == error_mark_node)
+     return decl;
+ 
+   current = current_scope ();
+   if (current == NULL_TREE)
+     current = current_namespace;
+ 
+   *new_type_p = 0;
+   
+   /* For a definition, we want to enter the containing scope
+      before looking up any base classes etc. Only do so, if this
+      is different to the current scope.  */
+   context = CP_DECL_CONTEXT (decl);
+ 
+   if (IMPLICIT_TYPENAME_P (context))
+     context = TREE_TYPE (context);
+ 
+   *new_type_p = (current != context
+ 		 && TREE_CODE (context) != TEMPLATE_TYPE_PARM
+ 	         && TREE_CODE (context) != BOUND_TEMPLATE_TEMPLATE_PARM);
+   if (*new_type_p)
+     push_scope (context);
+ 
+   if (TREE_CODE (TREE_TYPE (decl)) == RECORD_TYPE)
+     /* We might be specializing a template with a different
+        class-key.  */
+     CLASSTYPE_DECLARED_CLASS (TREE_TYPE (decl))
+       = (current_aggr == class_type_node);
+ 
+   return decl;
+ }
+ 
  #include "gt-cp-decl2.h"
diff -cprN gcc-33-save/gcc/cp/parse.y gcc-33-new/gcc/cp/parse.y
*** gcc-33-save/gcc/cp/parse.y	Sun Jul  6 17:19:35 2003
--- gcc-33-new/gcc/cp/parse.y	Mon Jul  7 20:44:02 2003
*************** class_head_defn:
*** 2491,2514 ****
  	| class_head_apparent_template '{'
  		{
  		  yyungetc ('{', 1);
! 		  $$.t = $1;
! 		  $$.new_type_flag = 0;
! 		  if (TREE_CODE (TREE_TYPE ($1)) == RECORD_TYPE)
! 		    /* We might be specializing a template with a different
! 		       class-key.  */
! 		    CLASSTYPE_DECLARED_CLASS (TREE_TYPE ($1))
! 		      = (current_aggr == class_type_node);
  		}
  	| class_head_apparent_template ':'
  		{
  		  yyungetc (':', 1);
! 		  $$.t = $1;
! 		  $$.new_type_flag = 0;
! 		  if (TREE_CODE (TREE_TYPE ($1)) == RECORD_TYPE)
! 		    /* We might be specializing a template with a different
! 		       class-key.  */
! 		    CLASSTYPE_DECLARED_CLASS (TREE_TYPE ($1))
! 		      = (current_aggr == class_type_node);
  		}
  	| aggr identifier_defn '{'
  		{
--- 2491,2504 ----
  	| class_head_apparent_template '{'
  		{
  		  yyungetc ('{', 1);
! 		  $$.t = handle_class_head_apparent_template
! 			   ($1, &$$.new_type_flag);
  		}
  	| class_head_apparent_template ':'
  		{
  		  yyungetc (':', 1);
! 		  $$.t = handle_class_head_apparent_template
! 			   ($1, &$$.new_type_flag);
  		}
  	| aggr identifier_defn '{'
  		{
diff -cprN gcc-33-save/gcc/cp/search.c gcc-33-new/gcc/cp/search.c
*** gcc-33-save/gcc/cp/search.c	Sun Jul  6 17:19:35 2003
--- gcc-33-new/gcc/cp/search.c	Mon Jul  7 20:44:02 2003
*************** void
*** 1048,1062 ****
  type_access_control (type, val)
       tree type, val;
  {
-   /* The check processing_specialization is here because the parser in 3.3
-      does not set current_class_type while parsing class head of class
-      template specialization.  Access checking, if performed, will be
-      evaluated in the wrong context so we disable it here.  This doesn't
-      apply to the new parser in 3.4.  */
    if (val == NULL_TREE
        || (TREE_CODE (val) != TEMPLATE_DECL && TREE_CODE (val) != TYPE_DECL)
!       || ! DECL_CLASS_SCOPE_P (val)
!       || processing_specialization)
      return;
  
    if (type_lookups == error_mark_node)
--- 1048,1056 ----
  type_access_control (type, val)
       tree type, val;
  {
    if (val == NULL_TREE
        || (TREE_CODE (val) != TEMPLATE_DECL && TREE_CODE (val) != TYPE_DECL)
!       || ! DECL_CLASS_SCOPE_P (val))
      return;
  
    if (type_lookups == error_mark_node)
diff -cprN gcc-33-save/gcc/testsuite/g++.dg/template/access12.C gcc-33-new/gcc/testsuite/g++.dg/template/access12.C
*** gcc-33-save/gcc/testsuite/g++.dg/template/access12.C	Thu Jan  1 07:00:00 1970
--- gcc-33-new/gcc/testsuite/g++.dg/template/access12.C	Sun Jul  6 21:19:24 2003
***************
*** 0 ****
--- 1,13 ----
+ // { dg-do compile }
+ 
+ // Origin: Giovanni Bajo <giovannibajo@libero.it>
+ 
+ // PR c++/10849: Incorrect access checking on class template partial
+ // specialization.
+ 
+ class X {
+   private:
+     template <typename T> struct Y;
+ };
+ 
+ template <typename T> struct X::Y<T*> {};


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