[C++ PATCH] Deferred access checking & template instantiation

Kriang Lerdsuwanakij lerdsuwa@users.sourceforge.net
Sat Jan 18 17:35:00 GMT 2003


Hi

The appended patch extends my earlier deferred access check
infrastructure to template instantiation.  Now make_typename_type
and such no longer need to know whether they are called from
the parser.  The 'tf_parsing' flag is now removed as well.

Bootstrapped and tested on i686-pc-linux-gnu with no regressions.
OK for the main trunk?

--Kriang


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

	* cp-tree.h (tsubst_flags_t): Remove tf_parsing.
	* decl.c (make_typename_type): Adjust.
	(make_unbound_class_template): Likewise.
	* parser.c (cp_parser_postfix_expression): Use tf_error.
	(cp_parser_elaborated_type_specifier): Likewise.
	(cp_parser_lookup_name): Likewise.
	(cp_parser_class_name): Use tf_error.  Remove tf_parsing.
	(cp_parser_template_argument): Remove tf_parsing.
	* pt.c (instantiate_class_template): Disable deferred
	access checks.

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

	* g++.dg/template/access8.C: New test.
	* g++.dg/template/access9.C: New test.


diff -cprN gcc-main-save/gcc/cp/cp-tree.h gcc-main-new/gcc/cp/cp-tree.h
*** gcc-main-save/gcc/cp/cp-tree.h	Fri Jan 17 19:13:57 2003
--- gcc-main-new/gcc/cp/cp-tree.h	Sat Jan 18 22:52:00 2003
*************** typedef enum tsubst_flags_t {
*** 3120,3129 ****
    tf_ignore_bad_quals = 1 << 3, /* ignore bad cvr qualifiers */
    tf_keep_type_decl = 1 << 4,	/* retain typedef type decls
  				   (make_typename_type use) */
!   tf_ptrmem_ok = 1 << 5,     /* pointers to member ok (internal
  				instantiate_type use) */
-   tf_parsing = 1 << 6	     /* called from parser
- 				(make_typename_type use) */
  } tsubst_flags_t;
  
  /* The kind of checking we can do looking in a class hierarchy.  */
--- 3120,3127 ----
    tf_ignore_bad_quals = 1 << 3, /* ignore bad cvr qualifiers */
    tf_keep_type_decl = 1 << 4,	/* retain typedef type decls
  				   (make_typename_type use) */
!   tf_ptrmem_ok = 1 << 5      /* pointers to member ok (internal
  				instantiate_type use) */
  } tsubst_flags_t;
  
  /* The kind of checking we can do looking in a class hierarchy.  */
diff -cprN gcc-main-save/gcc/cp/decl.c gcc-main-new/gcc/cp/decl.c
*** gcc-main-save/gcc/cp/decl.c	Fri Jan 17 19:13:59 2003
--- gcc-main-new/gcc/cp/decl.c	Sat Jan 18 22:48:56 2003
*************** make_typename_type (tree context, tree n
*** 5533,5544 ****
  	    }
  
  	  if (complain & tf_error)
! 	    {
! 	      if (complain & tf_parsing)
! 		perform_or_defer_access_check (context, tmpl);
! 	      else
! 		enforce_access (context, tmpl);
! 	    }
  
  	  return lookup_template_class (tmpl,
  					TREE_OPERAND (fullname, 1),
--- 5533,5539 ----
  	    }
  
  	  if (complain & tf_error)
! 	    perform_or_defer_access_check (context, tmpl);
  
  	  return lookup_template_class (tmpl,
  					TREE_OPERAND (fullname, 1),
*************** make_typename_type (tree context, tree n
*** 5568,5579 ****
  		}
  
  	      if (complain & tf_error)
! 		{
! 	      	  if (complain & tf_parsing)
! 		    perform_or_defer_access_check (context, t);
! 		  else
! 		    enforce_access (context, t);
! 		}
  
  	      if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl))
  		t = TREE_TYPE (t);
--- 5563,5569 ----
  		}
  
  	      if (complain & tf_error)
! 		perform_or_defer_access_check (context, t);
  
  	      if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl))
  		t = TREE_TYPE (t);
*************** make_unbound_class_template (tree contex
*** 5630,5641 ****
  	}
        
        if (complain & tf_error)
! 	{
! 	  if (complain & tf_parsing)
! 	    perform_or_defer_access_check (context, tmpl);
! 	  else
! 	    enforce_access (context, tmpl);
! 	}
  
        return tmpl;
      }
--- 5620,5626 ----
  	}
        
        if (complain & tf_error)
! 	perform_or_defer_access_check (context, tmpl);
  
        return tmpl;
      }
diff -cprN gcc-main-save/gcc/cp/parser.c gcc-main-new/gcc/cp/parser.c
*** gcc-main-save/gcc/cp/parser.c	Fri Jan 17 19:13:59 2003
--- gcc-main-new/gcc/cp/parser.c	Sat Jan 18 22:55:24 2003
*************** cp_parser_postfix_expression (cp_parser 
*** 3939,3946 ****
  	  id = cp_parser_identifier (parser);
  	/* Create a TYPENAME_TYPE to represent the type to which the
  	   functional cast is being performed.  */
! 	type = make_typename_type (parser->scope, id, 
! 				   /*complain=*/1);
  
  	postfix_expression = cp_parser_functional_cast (parser, type);
        }
--- 3939,3945 ----
  	  id = cp_parser_identifier (parser);
  	/* Create a TYPENAME_TYPE to represent the type to which the
  	   functional cast is being performed.  */
! 	type = make_typename_type (parser->scope, id, tf_error);
  
  	postfix_expression = cp_parser_functional_cast (parser, type);
        }
*************** cp_parser_template_argument (parser)
*** 8444,8450 ****
        if (template_p)
  	argument = make_unbound_class_template (TREE_OPERAND (argument, 0),
  						TREE_OPERAND (argument, 1),
! 						tf_error | tf_parsing);
        else if (TREE_CODE (argument) != TEMPLATE_DECL)
  	cp_parser_error (parser, "expected template-name");
      }
--- 8443,8449 ----
        if (template_p)
  	argument = make_unbound_class_template (TREE_OPERAND (argument, 0),
  						TREE_OPERAND (argument, 1),
! 						tf_error);
        else if (TREE_CODE (argument) != TEMPLATE_DECL)
  	cp_parser_error (parser, "expected template-name");
      }
*************** cp_parser_elaborated_type_specifier (par
*** 9024,9031 ****
  	 template will correspond to a class.  */
        else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
  	       && tag_type == typename_type)
! 	type = make_typename_type (parser->scope, decl,
! 				   /*complain=*/1);
        else 
  	type = TREE_TYPE (decl);
      }
--- 9023,9029 ----
  	 template will correspond to a class.  */
        else if (TREE_CODE (decl) == TEMPLATE_ID_EXPR
  	       && tag_type == typename_type)
! 	type = make_typename_type (parser->scope, decl, tf_error);
        else 
  	type = TREE_TYPE (decl);
      }
*************** cp_parser_elaborated_type_specifier (par
*** 9040,9047 ****
  
        /* For a `typename', we needn't call xref_tag.  */
        if (tag_type == typename_type)
! 	return make_typename_type (parser->scope, identifier, 
! 				   /*complain=*/1);
        /* Look up a qualified name in the usual way.  */
        if (parser->scope)
  	{
--- 9038,9045 ----
  
        /* For a `typename', we needn't call xref_tag.  */
        if (tag_type == typename_type)
! 	return make_typename_type (parser->scope, identifier, tf_error);
! 
        /* Look up a qualified name in the usual way.  */
        if (parser->scope)
  	{
*************** cp_parser_class_name (cp_parser *parser,
*** 11558,11565 ****
  
    /* If this is a typename, create a TYPENAME_TYPE.  */
    if (typename_p && decl != error_mark_node)
!     decl = TYPE_NAME (make_typename_type (scope, decl,
! 					  /*complain=*/1));
  
    /* Check to see that it is really the name of a class.  */
    if (TREE_CODE (decl) == TEMPLATE_ID_EXPR 
--- 11556,11562 ----
  
    /* If this is a typename, create a TYPENAME_TYPE.  */
    if (typename_p && decl != error_mark_node)
!     decl = TYPE_NAME (make_typename_type (scope, decl, tf_error));
  
    /* Check to see that it is really the name of a class.  */
    if (TREE_CODE (decl) == TEMPLATE_ID_EXPR 
*************** cp_parser_class_name (cp_parser *parser,
*** 11575,11582 ****
         standard does not seem to be definitive, but there is no other
         valid interpretation of the following `::'.  Therefore, those
         names are considered class-names.  */
!     decl = TYPE_NAME (make_typename_type (scope, decl, 
! 					  tf_error | tf_parsing));
    else if (decl == error_mark_node
  	   || TREE_CODE (decl) != TYPE_DECL
  	   || !IS_AGGR_TYPE (TREE_TYPE (decl)))
--- 11572,11578 ----
         standard does not seem to be definitive, but there is no other
         valid interpretation of the following `::'.  Therefore, those
         names are considered class-names.  */
!     decl = TYPE_NAME (make_typename_type (scope, decl, tf_error));
    else if (decl == error_mark_node
  	   || TREE_CODE (decl) != TYPE_DECL
  	   || !IS_AGGR_TYPE (TREE_TYPE (decl)))
*************** cp_parser_lookup_name (cp_parser *parser
*** 13481,13487 ****
  	       dependent.  */
  	    decl = TYPE_NAME (make_typename_type (parser->scope,
  						  name,
! 						  /*complain=*/1));
  	}
        else
  	{
--- 13477,13483 ----
  	       dependent.  */
  	    decl = TYPE_NAME (make_typename_type (parser->scope,
  						  name,
! 						  tf_error));
  	}
        else
  	{
diff -cprN gcc-main-save/gcc/cp/pt.c gcc-main-new/gcc/cp/pt.c
*** gcc-main-save/gcc/cp/pt.c	Fri Jan 17 19:13:59 2003
--- gcc-main-new/gcc/cp/pt.c	Sat Jan 18 23:11:35 2003
*************** instantiate_class_template (type)
*** 5192,5197 ****
--- 5192,5201 ----
       the process of being defined.  */
    TYPE_BEING_DEFINED (type) = 1;
  
+   /* We may be in the middle of deferred access check.  Disable
+      it now.  */
+   push_deferring_access_checks (false);
+ 
    maybe_push_to_top_level (uses_template_parms (type));
  
    if (t)
*************** instantiate_class_template (type)
*** 5521,5526 ****
--- 5525,5531 ----
  
    popclass ();
    pop_from_top_level ();
+   pop_deferring_access_checks ();
    pop_tinst_level ();
  
    if (TYPE_CONTAINS_VPTR_P (type))
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/template/access8.C gcc-main-new/gcc/testsuite/g++.dg/template/access8.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/access8.C	Thu Jan  1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/access8.C	Sat Jan 18 23:33:10 2003
***************
*** 0 ****
--- 1,16 ----
+ // Copyright (C) 2003 Free Software Foundation
+ // Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+ // { dg-do compile }
+ 
+ // Template instantiate during deferred access check
+ 
+ template <class T> struct C {
+   typedef typename T::X Y;
+ };
+ 
+ class A {
+   typedef int X;
+   template <class T> friend struct C;
+ };
+ 
+ C<A>::Y f(int);
diff -cprN gcc-main-save/gcc/testsuite/g++.dg/template/access9.C gcc-main-new/gcc/testsuite/g++.dg/template/access9.C
*** gcc-main-save/gcc/testsuite/g++.dg/template/access9.C	Thu Jan  1 07:00:00 1970
--- gcc-main-new/gcc/testsuite/g++.dg/template/access9.C	Sat Jan 18 23:33:14 2003
***************
*** 0 ****
--- 1,19 ----
+ // Copyright (C) 2003 Free Software Foundation
+ // Contributed by Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
+ // { dg-do compile }
+ 
+ // Template instantiate during deferred access check
+ 
+ template <void (*)(int)> struct C {
+   typedef int Y;
+ };
+ 
+ template <class T> void f(typename T::X) {
+ }
+ 
+ class A {
+   typedef int X;
+   template <class T> friend void f(typename T::X);
+ };
+ 
+ C<&f<A> >::Y g(int);



More information about the Gcc-patches mailing list