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] Remove scope_chain->check_access, fix PR9252 (a regression)


Hi

This is a continuation of my earlier patch (unreviewed)

	http://gcc.gnu.org/ml/gcc-patches/2003-04/msg00444.html

that unifies access checking disabling and deferring mechanisms
to use the same functions.  This patch completes the work
by removing the `scope_chain->check_access' field, and 
using `perform_or_defer_access_check' throughout the frontend.
PR c++/9252 is fixed as a by-product of not calling the function
`enforce_access' directly.

Bootstrapped and tested on i686-pc-linux-gnu with no regressions.
OK to commit this together with the earlier patch mentioned above
to the main trunk?

--Kriang


2003-04-15  Kriang Lerdsuwanakij  <lerdsuwa at users dot sourceforge dot net>

	PR c++/9252
	* cp-tree.h (saved_scope): Remove check_access field.
	(tsubst_flags_t): Remove tf_parsing.
	* decl.c (maybe_push_to_top_level): Don't initialize
	scope_chain->check_access.
	(make_typename_type, make_unbound_class_template): Don't use
	tf_parsing.
	(register_dtor_fn): Use push/pop_deferring_access_checks
	instead of scope_chain->check_access.
	* method.c (use_thunk): Likewise.
	* parser.c (cp_parser_explicit_instantiation
	(cp_parser_constructor_declarator_p): Don't call
	push/pop_deferring_access_checks here.
	(cp_parser_template_argument, cp_parser_class_name): Don't use
	tf_parsing.
	(yyparse): Check flag_access_control.
	* pt.c (instantiate_class_template): Call
	push/pop_deferring_access_checks.
	* semantics.c (push_deferring_access_checks): Propagate
	dk_no_check.
	(perform_or_defer_access_check): Make sure basetype_path is
	a type before comparison.
	* call.c (build_op_delete_call, build_over_call): Use
	perform_or_defer_access_check.
	* class.c (alter_access): Likewise.
	* init.c (build_offset_ref): Likewise.
	* lex.c (do_identifier): Likewise.
	* method.c (hack_identifier): Likewise.
	* search.c (lookup_member): Likewise.
	* semantics.c (finish_non_static_data_member): Likewise.
	(simplify_aggr_init_exprs_r): Use push/pop_deferring_access_checks
	instead of flag_access_control.

2003-04-15  Kriang Lerdsuwanakij  <lerdsuwa at users dot sourceforge dot net>

	PR c++/9252
	* g++.dg/parse/access8.C: New test.
	* g++.dg/parse/access9.C: New test.


diff -cprN gcc-main-save/gcc/cp/call.c gcc-main-new/gcc/cp/call.c
*** gcc-main-save/gcc/cp/call.c	Sun Mar 30 00:55:57 2003
--- gcc-main-new/gcc/cp/call.c	Mon Apr 14 19:15:37 2003
*************** build_op_delete_call (enum tree_code cod
*** 4033,4039 ****
        /* If the FN is a member function, make sure that it is
  	 accessible.  */
        if (DECL_CLASS_SCOPE_P (fn))
! 	enforce_access (type, fn);
  
        if (pass == 0)
  	args = tree_cons (NULL_TREE, addr, args);
--- 4033,4039 ----
        /* If the FN is a member function, make sure that it is
  	 accessible.  */
        if (DECL_CLASS_SCOPE_P (fn))
! 	perform_or_defer_access_check (type, fn);
  
        if (pass == 0)
  	args = tree_cons (NULL_TREE, addr, args);
*************** build_over_call (struct z_candidate *can
*** 4484,4490 ****
        joust (cand, WRAPPER_ZC (TREE_VALUE (val)), 1);
  
    if (DECL_FUNCTION_MEMBER_P (fn))
!     enforce_access (cand->access_path, fn);
  
    if (args && TREE_CODE (args) != TREE_LIST)
      args = build_tree_list (NULL_TREE, args);
--- 4484,4490 ----
        joust (cand, WRAPPER_ZC (TREE_VALUE (val)), 1);
  
    if (DECL_FUNCTION_MEMBER_P (fn))
!     perform_or_defer_access_check (cand->access_path, fn);
  
    if (args && TREE_CODE (args) != TREE_LIST)
      args = build_tree_list (NULL_TREE, args);
diff -cprN gcc-main-save/gcc/cp/class.c gcc-main-new/gcc/cp/class.c
*** gcc-main-save/gcc/cp/class.c	Sun Apr  6 20:30:41 2003
--- gcc-main-new/gcc/cp/class.c	Mon Apr 14 19:15:37 2003
*************** alter_access (tree t, tree fdecl, tree a
*** 1086,1092 ****
      }
    else
      {
!       enforce_access (t, fdecl);
        DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
        return 1;
      }
--- 1086,1092 ----
      }
    else
      {
!       perform_or_defer_access_check (t, fdecl);
        DECL_ACCESS (fdecl) = tree_cons (t, access, DECL_ACCESS (fdecl));
        return 1;
      }
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	Mon Apr 14 17:23:01 2003
--- gcc-main-new/gcc/cp/cp-tree.h	Tue Apr 15 15:41:53 2003
*************** struct saved_scope GTY(())
*** 726,732 ****
    int x_processing_specialization;
    bool x_processing_explicit_instantiation;
    int need_pop_function_context;
-   int check_access;
  
    struct stmt_tree_s x_stmt_tree;
  
--- 726,731 ----
*************** typedef enum tsubst_flags_t {
*** 3033,3042 ****
    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.  */
--- 3032,3039 ----
    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	Sun Apr  6 20:30:41 2003
--- gcc-main-new/gcc/cp/decl.c	Mon Apr 14 19:15:37 2003
*************** maybe_push_to_top_level (int pseudo)
*** 2243,2249 ****
    s->need_pop_function_context = need_pop;
    s->function_decl = current_function_decl;
    s->last_parms = last_function_parms;
-   s->check_access = flag_access_control;
  
    scope_chain = s;
    current_function_decl = NULL_TREE;
--- 2243,2248 ----
*************** make_typename_type (tree context, tree n
*** 5478,5489 ****
  	    }
  
  	  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),
--- 5477,5483 ----
  	    }
  
  	  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
*** 5513,5524 ****
  		}
  
  	      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);
--- 5507,5513 ----
  		}
  
  	      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
*** 5575,5586 ****
  	}
        
        if (complain & tf_error)
! 	{
! 	  if (complain & tf_parsing)
! 	    perform_or_defer_access_check (context, tmpl);
! 	  else
! 	    enforce_access (context, tmpl);
! 	}
  
        return tmpl;
      }
--- 5564,5570 ----
  	}
        
        if (complain & tf_error)
! 	perform_or_defer_access_check (context, tmpl);
  
        return tmpl;
      }
*************** register_dtor_fn (tree decl)
*** 8428,8434 ****
    tree compound_stmt;
    tree args;
    tree fcall;
-   int saved_flag_access_control;
  
    if (TYPE_HAS_TRIVIAL_DESTRUCTOR (TREE_TYPE (decl)))
      return;
--- 8412,8417 ----
*************** register_dtor_fn (tree decl)
*** 8445,8454 ****
       to the original function, rather than the anonymous one.  That
       will make the back-end think that nested functions are in use,
       which causes confusion.  */
!   saved_flag_access_control = flag_access_control;
!   scope_chain->check_access = flag_access_control = 0;
    fcall = build_cleanup (decl);
!   scope_chain->check_access = flag_access_control = saved_flag_access_control;
  
    /* Create the body of the anonymous function.  */
    compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
--- 8428,8437 ----
       to the original function, rather than the anonymous one.  That
       will make the back-end think that nested functions are in use,
       which causes confusion.  */
!   
!   push_deferring_access_checks (dk_no_check);
    fcall = build_cleanup (decl);
!   pop_deferring_access_checks ();
  
    /* Create the body of the anonymous function.  */
    compound_stmt = begin_compound_stmt (/*has_no_scope=*/0);
diff -cprN gcc-main-save/gcc/cp/init.c gcc-main-new/gcc/cp/init.c
*** gcc-main-save/gcc/cp/init.c	Tue Mar 18 22:45:20 2003
--- gcc-main-new/gcc/cp/init.c	Mon Apr 14 19:15:37 2003
*************** build_offset_ref (type, name)
*** 1662,1669 ****
  	  t = OVL_CURRENT (t);
  
  	  /* unique functions are handled easily.  */
! 	  if (!enforce_access (basebinfo, t))
! 	    return error_mark_node;
  	  mark_used (t);
  	  if (DECL_STATIC_FUNCTION_P (t))
  	    return t;
--- 1662,1668 ----
  	  t = OVL_CURRENT (t);
  
  	  /* unique functions are handled easily.  */
! 	  perform_or_defer_access_check (basebinfo, t);
  	  mark_used (t);
  	  if (DECL_STATIC_FUNCTION_P (t))
  	    return t;
diff -cprN gcc-main-save/gcc/cp/lex.c gcc-main-new/gcc/cp/lex.c
*** gcc-main-save/gcc/cp/lex.c	Sun Mar  9 21:21:31 2003
--- gcc-main-new/gcc/cp/lex.c	Mon Apr 14 19:15:37 2003
*************** do_identifier (token, args)
*** 790,796 ****
      {
        /* Check access.  */
        if (IDENTIFIER_CLASS_VALUE (token) == id)
! 	enforce_access (CP_DECL_CONTEXT(id), id);
        if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id))
  	id = DECL_INITIAL (id);
      }
--- 790,796 ----
      {
        /* Check access.  */
        if (IDENTIFIER_CLASS_VALUE (token) == id)
! 	perform_or_defer_access_check (CP_DECL_CONTEXT(id), id);
        if (!processing_template_decl || DECL_TEMPLATE_PARM_P (id))
  	id = DECL_INITIAL (id);
      }
diff -cprN gcc-main-save/gcc/cp/method.c gcc-main-new/gcc/cp/method.c
*** gcc-main-save/gcc/cp/method.c	Sun Apr  6 20:30:41 2003
--- gcc-main-new/gcc/cp/method.c	Mon Apr 14 19:15:37 2003
*************** hack_identifier (tree value, tree name)
*** 179,185 ****
  	{
  	  tree path;
  	  path = currently_open_derived_class (DECL_CONTEXT (value));
! 	  enforce_access (path, value);
  	}
      }
    else if (TREE_CODE (value) == TREE_LIST 
--- 179,185 ----
  	{
  	  tree path;
  	  path = currently_open_derived_class (DECL_CONTEXT (value));
! 	  perform_or_defer_access_check (path, value);
  	}
      }
    else if (TREE_CODE (value) == TREE_LIST 
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 449,455 ****
  	 doesn't work for varargs.  */
  
        tree a, t;
-       int saved_check_access;
  
        if (varargs_function_p (function))
  	error ("generic thunk code fails for method `%#D' which uses `...'",
--- 449,454 ----
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 472,479 ****
        /* We don't bother with a body block for thunks.  */
  
        /* There's no need to check accessibility inside the thunk body.  */
!       saved_check_access = scope_chain->check_access;
!       scope_chain->check_access = 0;
  
        t = a;
        if (this_adjusting)
--- 471,477 ----
        /* We don't bother with a body block for thunks.  */
  
        /* There's no need to check accessibility inside the thunk body.  */
!       push_deferring_access_checks (dk_no_check);
  
        t = a;
        if (this_adjusting)
*************** use_thunk (tree thunk_fndecl, bool emit_
*** 503,509 ****
        DECL_IGNORED_P (thunk_fndecl) = 1;
  
        /* Re-enable access control.  */
!       scope_chain->check_access = saved_check_access;
  
        expand_body (finish_function (0));
      }
--- 501,507 ----
        DECL_IGNORED_P (thunk_fndecl) = 1;
  
        /* Re-enable access control.  */
!       pop_deferring_access_checks ();
  
        expand_body (finish_function (0));
      }
diff -cprN gcc-main-save/gcc/cp/parser.c gcc-main-new/gcc/cp/parser.c
*** gcc-main-save/gcc/cp/parser.c	Mon Apr 14 17:23:01 2003
--- gcc-main-new/gcc/cp/parser.c	Mon Apr 14 21:20:49 2003
*************** cp_parser_template_argument (cp_parser* 
*** 8245,8251 ****
        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");
      }
--- 8245,8251 ----
        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_explicit_instantiation (cp_par
*** 8302,8308 ****
    begin_explicit_instantiation ();
    /* [temp.explicit] says that we are supposed to ignore access
       control while processing explicit instantiation directives.  */
!   scope_chain->check_access = 0;
    /* Parse a decl-specifier-seq.  */
    decl_specifiers 
      = cp_parser_decl_specifier_seq (parser,
--- 8302,8308 ----
    begin_explicit_instantiation ();
    /* [temp.explicit] says that we are supposed to ignore access
       control while processing explicit instantiation directives.  */
!   push_deferring_access_checks (dk_no_check);
    /* Parse a decl-specifier-seq.  */
    decl_specifiers 
      = cp_parser_decl_specifier_seq (parser,
*************** cp_parser_explicit_instantiation (cp_par
*** 8337,8343 ****
    /* We're done with the instantiation.  */
    end_explicit_instantiation ();
    /* Turn access control back on.  */
!   scope_chain->check_access = flag_access_control;
  
    cp_parser_consume_semicolon_at_end_of_statement (parser);
  }
--- 8337,8343 ----
    /* We're done with the instantiation.  */
    end_explicit_instantiation ();
    /* Turn access control back on.  */
!   pop_deferring_access_checks ();
  
    cp_parser_consume_semicolon_at_end_of_statement (parser);
  }
*************** cp_parser_class_name (cp_parser *parser,
*** 11391,11398 ****
         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)))
--- 11391,11397 ----
         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_class_specifier (cp_parser* pa
*** 11451,11456 ****
--- 11450,11456 ----
    saved_num_template_parameter_lists 
      = parser->num_template_parameter_lists; 
    parser->num_template_parameter_lists = 0;
+ 
    /* Start the class.  */
    type = begin_class_definition (type);
    if (type == error_mark_node)
*************** cp_parser_constructor_declarator_p (cp_p
*** 13647,13654 ****
    /* Assume that we are looking at a constructor declarator.  */
    constructor_p = true;
  
-   push_deferring_access_checks (dk_no_check);
- 
    /* Look for the optional `::' operator.  */
    cp_parser_global_scope_opt (parser,
  			      /*current_scope_valid_p=*/false);
--- 13647,13652 ----
*************** cp_parser_constructor_declarator_p (cp_p
*** 13690,13697 ****
        constructor_p = !cp_parser_error_occurred (parser);
      }
  
-   pop_deferring_access_checks ();
- 
    /* If we're still considering a constructor, we have to see a `(',
       to begin the parameter-declaration-clause, followed by either a
       `)', an `...', or a decl-specifier.  We need to check for a
--- 13688,13693 ----
*************** yyparse (void)
*** 14665,14671 ****
    bool error_occurred;
  
    the_parser = cp_parser_new ();
!   push_deferring_access_checks (dk_no_deferred);
    error_occurred = cp_parser_translation_unit (the_parser);
    the_parser = NULL;
    
--- 14661,14668 ----
    bool error_occurred;
  
    the_parser = cp_parser_new ();
!   push_deferring_access_checks (flag_access_control
! 				? dk_no_deferred : dk_no_check);
    error_occurred = cp_parser_translation_unit (the_parser);
    the_parser = NULL;
    
diff -cprN gcc-main-save/gcc/cp/pt.c gcc-main-new/gcc/cp/pt.c
*** gcc-main-save/gcc/cp/pt.c	Sun Mar 30 00:55:57 2003
--- gcc-main-new/gcc/cp/pt.c	Mon Apr 14 19:16:32 2003
*************** instantiate_class_template (type)
*** 5252,5257 ****
--- 5252,5261 ----
       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)
*** 5562,5567 ****
--- 5566,5572 ----
  
    popclass ();
    pop_from_top_level ();
+   pop_deferring_access_checks ();
    pop_tinst_level ();
  
    if (TYPE_CONTAINS_VPTR_P (type))
diff -cprN gcc-main-save/gcc/cp/search.c gcc-main-new/gcc/cp/search.c
*** gcc-main-save/gcc/cp/search.c	Wed Apr  2 21:02:45 2003
--- gcc-main-new/gcc/cp/search.c	Mon Apr 14 19:15:37 2003
*************** accessible_p (tree type, tree decl)
*** 910,919 ****
       accessibility in TYPE.  */
    int protected_ok = 0;
  
-   /* If we're not checking access, everything is accessible.  */
-   if (!scope_chain->check_access)
-     return 1;
- 
    /* If this declaration is in a block or namespace scope, there's no
       access control.  */
    if (!TYPE_P (context_for_name_lookup (decl)))
--- 910,915 ----
*************** lookup_member (tree xbasetype, tree name
*** 1290,1298 ****
  
       In the case of overloaded function names, access control is
       applied to the function selected by overloaded resolution.  */
!   if (rval && protect && !is_overloaded_fn (rval)
!       && !enforce_access (xbasetype, rval))
!     return error_mark_node;
  
    if (errstr && protect)
      {
--- 1286,1293 ----
  
       In the case of overloaded function names, access control is
       applied to the function selected by overloaded resolution.  */
!   if (rval && protect && !is_overloaded_fn (rval))
!     perform_or_defer_access_check (xbasetype, rval);
  
    if (errstr && protect)
      {
diff -cprN gcc-main-save/gcc/cp/semantics.c gcc-main-new/gcc/cp/semantics.c
*** gcc-main-save/gcc/cp/semantics.c	Mon Apr 14 17:23:01 2003
--- gcc-main-new/gcc/cp/semantics.c	Mon Apr 14 20:38:46 2003
*************** void push_deferring_access_checks (defer
*** 141,146 ****
--- 141,152 ----
  {
    deferred_access *d;
  
+   /* For context like template instantiation, access checking
+      disabling applies to all nested context.  */
+   if (deferred_access_stack
+       && deferred_access_stack->deferring_access_checks_kind == dk_no_check)
+     deferring = dk_no_check;
+ 
    /* Recycle previously used free store if available.  */
    if (deferred_access_free_list)
      {
*************** void perform_or_defer_access_check (tree
*** 266,271 ****
--- 272,278 ----
         check;
         check = TREE_CHAIN (check))
      if (TREE_VALUE (check) == decl
+ 	&& TYPE_P (TREE_PURPOSE (check))
  	&& same_type_p (TREE_PURPOSE (check), class_type))
        return;
    /* If not, record the check.  */
*************** finish_non_static_data_member (tree decl
*** 1276,1282 ****
  	    access_type = DECL_CONTEXT (access_type);
  	}
  
!       enforce_access (access_type, decl);
  
        /* If the data member was named `C::M', convert `*this' to `C'
  	 first.  */
--- 1283,1289 ----
  	    access_type = DECL_CONTEXT (access_type);
  	}
  
!       perform_or_defer_access_check (access_type, decl);
  
        /* If the data member was named `C::M', convert `*this' to `C'
  	 first.  */
*************** simplify_aggr_init_exprs_r (tp, walk_sub
*** 2299,2310 ****
        /* If we're using the non-reentrant PCC calling convention, then we
  	 need to copy the returned value out of the static buffer into the
  	 SLOT.  */
!       int old_ac = flag_access_control;
! 
!       flag_access_control = 0;
        call_expr = build_aggr_init (slot, call_expr,
  				   DIRECT_BIND | LOOKUP_ONLYCONVERTING);
!       flag_access_control = old_ac;
      }
  
    /* We want to use the value of the initialized location as the
--- 2306,2315 ----
        /* If we're using the non-reentrant PCC calling convention, then we
  	 need to copy the returned value out of the static buffer into the
  	 SLOT.  */
!       push_deferring_access_checks (dk_no_check);
        call_expr = build_aggr_init (slot, call_expr,
  				   DIRECT_BIND | LOOKUP_ONLYCONVERTING);
!       pop_deferring_access_checks ();
      }
  
    /* We want to use the value of the initialized location as the
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	Mon Apr 14 21:39:36 2003
***************
*** 0 ****
--- 1,16 ----
+ // Copyright (C) 2003 Free Software Foundation
+ // Contributed by Kriang Lerdsuwanakij <lerdsuwa at users dot sourceforge dot 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	Mon Apr 14 21:39:36 2003
***************
*** 0 ****
--- 1,19 ----
+ // Copyright (C) 2003 Free Software Foundation
+ // Contributed by Kriang Lerdsuwanakij <lerdsuwa at users dot sourceforge dot 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);


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