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.4] Fix PR19258 (incorrect scope for friend definedin-class)


Hi

This patch fixes PR19258 for 3.4 branch.  The only difference
to the mainline (committed) version at:

http://gcc.gnu.org/ml/gcc-patches/2005-01/msg00271.html

is that we need to check DECL_FRIEND_CONTEXT in
cp_parser_late_parsing_default_args as well.  The mainline doesn't
need this because the push/pop_nested_class calls were done once
elsewhere with the correct scope rather than calling here for
every default argument processed.

Tested on i686-pc-linux-gnu. OK for the mainline?

--Kriang
2005-01-18  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/19258
	* parser.c (cp_parser_late_parsing_default_args): Handle friend
	defined in class.
	* pt.c (push_access_scope, pop_access_scope): Likewise.

2005-01-18  Kriang Lerdsuwanakij  <lerdsuwa@users.sourceforge.net>

	PR c++/19258
	* g++.dg/lookup/friend6.C: New test.


diff -cprN gcc-34-save/gcc/cp/parser.c gcc-34-new/gcc/cp/parser.c
*** gcc-34-save/gcc/cp/parser.c	Sun Dec 19 19:10:47 2004
--- gcc-34-new/gcc/cp/parser.c	Mon Jan 17 23:49:20 2005
***************  (cp_
*** 14843,14852 ****
        saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
        parser->local_variables_forbidden_p = true;
         /* Parse the assignment-expression.  */
!       if (DECL_CLASS_SCOPE_P (fn))
  	push_nested_class (DECL_CONTEXT (fn));
        TREE_PURPOSE (parameters) = cp_parser_assignment_expression (parser);
!       if (DECL_CLASS_SCOPE_P (fn))
  	pop_nested_class ();
  
        /* If the token stream has not been completely used up, then
--- 14843,14854 ----
        saved_local_variables_forbidden_p = parser->local_variables_forbidden_p;
        parser->local_variables_forbidden_p = true;
         /* Parse the assignment-expression.  */
!       if (DECL_FRIEND_CONTEXT (fn))
! 	push_nested_class (DECL_FRIEND_CONTEXT (fn));
!       else if (DECL_CLASS_SCOPE_P (fn))
  	push_nested_class (DECL_CONTEXT (fn));
        TREE_PURPOSE (parameters) = cp_parser_assignment_expression (parser);
!       if (DECL_FRIEND_CONTEXT (fn) || DECL_CLASS_SCOPE_P (fn))
  	pop_nested_class ();
  
        /* If the token stream has not been completely used up, then
diff -cprN gcc-34-save/gcc/cp/pt.c gcc-34-new/gcc/cp/pt.c
*** gcc-34-save/gcc/cp/pt.c	Tue Jan 18 19:29:55 2005
--- gcc-34-new/gcc/cp/pt.c	Sun Jan 16 23:45:08 2005
*************** push_access_scope (tree t)
*** 180,186 ****
  		      || TREE_CODE (t) == VAR_DECL,
  		      0);
  
!   if (DECL_CLASS_SCOPE_P (t))
      push_nested_class (DECL_CONTEXT (t));
    else
      push_to_top_level ();
--- 180,188 ----
  		      || TREE_CODE (t) == VAR_DECL,
  		      0);
  
!   if (DECL_FRIEND_CONTEXT (t))
!     push_nested_class (DECL_FRIEND_CONTEXT (t));
!   else if (DECL_CLASS_SCOPE_P (t))
      push_nested_class (DECL_CONTEXT (t));
    else
      push_to_top_level ();
*************** pop_access_scope (tree t)
*** 205,211 ****
        saved_access_scope = TREE_CHAIN (saved_access_scope);
      }
  
!   if (DECL_CLASS_SCOPE_P (t))
      pop_nested_class ();
    else
      pop_from_top_level ();
--- 207,213 ----
        saved_access_scope = TREE_CHAIN (saved_access_scope);
      }
  
!   if (DECL_FRIEND_CONTEXT (t) || DECL_CLASS_SCOPE_P (t))
      pop_nested_class ();
    else
      pop_from_top_level ();
diff -cprN gcc-34-save/gcc/testsuite/g++.dg/lookup/friend6.C gcc-34-new/gcc/testsuite/g++.dg/lookup/friend6.C
*** gcc-34-save/gcc/testsuite/g++.dg/lookup/friend6.C	Thu Jan  1 07:00:00 1970
--- gcc-34-new/gcc/testsuite/g++.dg/lookup/friend6.C	Wed Jan  5 17:14:07 2005
***************
*** 0 ****
--- 1,15 ----
+ // { dg-do compile }
+ 
+ // Origin: Matt Austern <austern@apple.com>
+ 
+ // PR c++/19258: Wrong lookup scope for friend defined in class.
+ 
+ class X {
+   template<class T> friend int ff(T*, int y=anX.x) { return y; }
+   int f() { return ff(&anX); }
+ 
+   static X anX;
+   int x;
+ };
+ 
+ X dummy;

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