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++] Fix 19030 - ICE


Hi,

This patch fixes 19030 an ICE after invalid.  We were failing to
pop a scope during error recovery.  The current push_scope
interface made it hard to pop the scope in this case, as we were fishing
it out of the decl we hoped to create (but is error_mark for this case).
I changed push_scope to return the scope that should be popped (or NULL),
rather than a bool  In adjusting the callers, I found another place,
cp_parser_class_head, where we would fail to pop a scope in an error
situation -- it also had an unneccessary pop/push sequence, which I
corrected.

booted & tested on i686-pc-linux-gnu.

nathan

--
Nathan Sidwell    ::   http://www.codesourcery.com   ::     CodeSourcery LLC
nathan@codesourcery.com    ::     http://www.planetfall.pwp.blueyonder.co.uk

2005-01-05  Nathan Sidwell  <nathan@codesourcery.com>

	PR c++/19030
	* cp-tree.h (start_decl): Take pointer to pushed scope, not bool.
	* name-lookup.h (push_scope): Return pushed scope, not flag.
	* name-lookup.c (push_scope): Return scope that should be popped,
	not a flag.
	* decl.c (start_decl): Adjust.
	(grokfndecl): Adjust scope push and pop.
	* decl2.c (check_classfn): Likewise.
	* parser.c (cp_parser_condition, cp_parser_conversion_function_id,
	cp_parser_init_declarator, cp_parser_direct_declarator,
	cp_parser_class_specifier, cp_parser_class_head,
	cp_parser_lookup_name,
	cp_parser_constructor_declarator_p): Likewise.
	* pt.c (instantiate_class_template,
	resolve_typename_type): Likewise.

Index: cp/cp-tree.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/cp-tree.h,v
retrieving revision 1.1086
diff -c -3 -p -r1.1086 cp-tree.h
*** cp/cp-tree.h	30 Dec 2004 23:29:29 -0000	1.1086
--- cp/cp-tree.h	4 Jan 2005 16:21:41 -0000
***************
*** 1,6 ****
  /* Definitions for C++ parsing and type checking.
     Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
!    2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
     Contributed by Michael Tiemann (tiemann@cygnus.com)
  
  This file is part of GCC.
--- 1,6 ----
  /* Definitions for C++ parsing and type checking.
     Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
!    2000, 2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
     Contributed by Michael Tiemann (tiemann@cygnus.com)
  
  This file is part of GCC.
*************** extern int init_type_desc			(void);
*** 3780,3786 ****
  extern tree check_tag_decl			(cp_decl_specifier_seq *);
  extern tree shadow_tag				(cp_decl_specifier_seq *);
  extern tree groktypename			(cp_decl_specifier_seq *, const cp_declarator *);
! extern tree start_decl				(const cp_declarator *, cp_decl_specifier_seq *, int, tree, tree, bool *);
  extern void start_decl_1			(tree);
  extern void cp_finish_decl			(tree, tree, tree, int);
  extern void finish_decl				(tree, tree, tree);
--- 3780,3786 ----
  extern tree check_tag_decl			(cp_decl_specifier_seq *);
  extern tree shadow_tag				(cp_decl_specifier_seq *);
  extern tree groktypename			(cp_decl_specifier_seq *, const cp_declarator *);
! extern tree start_decl				(const cp_declarator *, cp_decl_specifier_seq *, int, tree, tree, tree *);
  extern void start_decl_1			(tree);
  extern void cp_finish_decl			(tree, tree, tree, int);
  extern void finish_decl				(tree, tree, tree);
Index: cp/decl.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl.c,v
retrieving revision 1.1350
diff -c -3 -p -r1.1350 decl.c
*** cp/decl.c	1 Jan 2005 16:15:17 -0000	1.1350
--- cp/decl.c	4 Jan 2005 16:22:04 -0000
***************
*** 1,6 ****
  /* Process declarations and variables for C++ compiler.
     Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
!    2001, 2002, 2003, 2004,2005  Free Software Foundation, Inc.
     Contributed by Michael Tiemann (tiemann@cygnus.com)
  
  This file is part of GCC.
--- 1,6 ----
  /* Process declarations and variables for C++ compiler.
     Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
!    2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
     Contributed by Michael Tiemann (tiemann@cygnus.com)
  
  This file is part of GCC.
*************** start_decl (const cp_declarator *declara
*** 3687,3699 ****
              int initialized,
              tree attributes,
              tree prefix_attributes, 
! 	    bool *pop_scope_p)
  {
    tree decl;
    tree type, tem;
    tree context;
  
!   *pop_scope_p = false;
   
    /* This should only be done once on the top most decl.  */
    if (have_extern_spec)
--- 3687,3699 ----
              int initialized,
              tree attributes,
              tree prefix_attributes, 
! 	    tree *pushed_scope_p)
  {
    tree decl;
    tree type, tem;
    tree context;
  
!   *pushed_scope_p = NULL_TREE;
   
    /* This should only be done once on the top most decl.  */
    if (have_extern_spec)
*************** start_decl (const cp_declarator *declara
*** 3725,3735 ****
    context = DECL_CONTEXT (decl);
  
    if (context)
!     *pop_scope_p = push_scope (context);
    
!   /* We are only interested in class contexts, later.  */
!   if (context && TREE_CODE (context) == NAMESPACE_DECL)
!     context = NULL_TREE;
  
    if (initialized)
      /* Is it valid for this decl to have an initializer at all?
--- 3725,3737 ----
    context = DECL_CONTEXT (decl);
  
    if (context)
!     {
!       *pushed_scope_p = push_scope (context);
    
!       /* We are only interested in class contexts, later.  */
!       if (TREE_CODE (context) == NAMESPACE_DECL)
! 	context = NULL_TREE;
!     }
  
    if (initialized)
      /* Is it valid for this decl to have an initializer at all?
*************** grokfndecl (tree ctype,
*** 5893,5899 ****
        if (old_decl)
  	{
  	  tree ok;
! 	  bool pop_p;
  
  	  /* Since we've smashed OLD_DECL to its
  	     DECL_TEMPLATE_RESULT, we must do the same to DECL.  */
--- 5895,5901 ----
        if (old_decl)
  	{
  	  tree ok;
! 	  tree pushed_scope;
  
  	  /* Since we've smashed OLD_DECL to its
  	     DECL_TEMPLATE_RESULT, we must do the same to DECL.  */
*************** grokfndecl (tree ctype,
*** 5902,5911 ****
  
  	  /* Attempt to merge the declarations.  This can fail, in
  	     the case of some invalid specialization declarations.  */
! 	  pop_p = push_scope (ctype);
  	  ok = duplicate_decls (decl, old_decl);
! 	  if (pop_p)
! 	    pop_scope (ctype);
  	  if (!ok)
  	    {
  	      error ("no %q#D member function declared in class %qT",
--- 5904,5913 ----
  
  	  /* Attempt to merge the declarations.  This can fail, in
  	     the case of some invalid specialization declarations.  */
! 	  pushed_scope = push_scope (ctype);
  	  ok = duplicate_decls (decl, old_decl);
! 	  if (pushed_scope)
! 	    pop_scope (pushed_scope);
  	  if (!ok)
  	    {
  	      error ("no %q#D member function declared in class %qT",
Index: cp/decl2.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/decl2.c,v
retrieving revision 1.763
diff -c -3 -p -r1.763 decl2.c
*** cp/decl2.c	1 Jan 2005 01:43:12 -0000	1.763
--- cp/decl2.c	4 Jan 2005 16:22:11 -0000
***************
*** 1,6 ****
  /* Process declarations and variables for C++ compiler.
     Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
!    1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
     Hacked by Michael Tiemann (tiemann@cygnus.com)
  
  This file is part of GCC.
--- 1,6 ----
  /* Process declarations and variables for C++ compiler.
     Copyright (C) 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
!    1999, 2000, 2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
     Hacked by Michael Tiemann (tiemann@cygnus.com)
  
  This file is part of GCC.
*************** check_classfn (tree ctype, tree function
*** 627,636 ****
        VEC(tree) *methods = CLASSTYPE_METHOD_VEC (ctype);
        tree fndecls, fndecl = 0;
        bool is_conv_op;
!       bool pop_p;
        const char *format = NULL;
        
!       pop_p = push_scope (ctype);
        for (fndecls = VEC_index (tree, methods, ix);
  	   fndecls; fndecls = OVL_NEXT (fndecls))
  	{
--- 627,636 ----
        VEC(tree) *methods = CLASSTYPE_METHOD_VEC (ctype);
        tree fndecls, fndecl = 0;
        bool is_conv_op;
!       tree pushed_scope;
        const char *format = NULL;
        
!       pushed_scope = push_scope (ctype);
        for (fndecls = VEC_index (tree, methods, ix);
  	   fndecls; fndecls = OVL_NEXT (fndecls))
  	{
*************** check_classfn (tree ctype, tree function
*** 669,676 ****
  		      == DECL_TI_TEMPLATE (fndecl))))
  	    break;
  	}
!       if (pop_p)
! 	pop_scope (ctype);
        if (fndecls)
  	return OVL_CURRENT (fndecls);
        error ("prototype for %q#D does not match any in class %qT",
--- 669,676 ----
  		      == DECL_TI_TEMPLATE (fndecl))))
  	    break;
  	}
!       if (pushed_scope)
! 	pop_scope (pushed_scope);
        if (fndecls)
  	return OVL_CURRENT (fndecls);
        error ("prototype for %q#D does not match any in class %qT",
Index: cp/name-lookup.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.c,v
retrieving revision 1.104
diff -c -3 -p -r1.104 name-lookup.c
*** cp/name-lookup.c	30 Dec 2004 23:29:33 -0000	1.104
--- cp/name-lookup.c	4 Jan 2005 16:22:20 -0000
***************
*** 1,5 ****
  /* Definitions for C++ name lookup routines.
!    Copyright (C) 2003, 2004 Free Software Foundation, Inc.
     Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
  
  This file is part of GCC.
--- 1,5 ----
  /* Definitions for C++ name lookup routines.
!    Copyright (C) 2003, 2004, 2005  Free Software Foundation, Inc.
     Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
  
  This file is part of GCC.
*************** is_ancestor (tree root, tree child)
*** 2214,2229 ****
      }
  }
  
! /* Enter the class or namespace scope indicated by T suitable for
!    name lookup.  T can be arbitrary scope, not necessary nested inside
!    the current scope.  Returns TRUE iff pop_scope should be called
!    later to exit this scope.  */
  
! bool
  push_scope (tree t)
  {
-   bool pop = true;
- 
    if (TREE_CODE (t) == NAMESPACE_DECL)
      push_decl_namespace (t);
    else if (CLASS_TYPE_P (t))
--- 2214,2227 ----
      }
  }
  
! /* Enter the class or namespace scope indicated by T suitable for name
!    lookup.  T can be arbitrary scope, not necessary nested inside the
!    current scope.  Returns a non-null scope to pop iff pop_scope
!    should be called later to exit this scope.  */
  
! tree
  push_scope (tree t)
  {
    if (TREE_CODE (t) == NAMESPACE_DECL)
      push_decl_namespace (t);
    else if (CLASS_TYPE_P (t))
*************** push_scope (tree t)
*** 2236,2245 ****
  	   need to re-enter the scope.  Since we are not actually
  	   pushing a new scope, our caller should not call
  	   pop_scope.  */
! 	pop = false;
      }
  
!   return pop;
  }
  
  /* Leave scope pushed by push_scope.  */
--- 2234,2243 ----
  	   need to re-enter the scope.  Since we are not actually
  	   pushing a new scope, our caller should not call
  	   pop_scope.  */
! 	t = NULL_TREE;
      }
  
!   return t;
  }
  
  /* Leave scope pushed by push_scope.  */
Index: cp/name-lookup.h
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/name-lookup.h,v
retrieving revision 1.34
diff -c -3 -p -r1.34 name-lookup.h
*** cp/name-lookup.h	30 Dec 2004 23:29:33 -0000	1.34
--- cp/name-lookup.h	4 Jan 2005 16:22:24 -0000
***************
*** 1,5 ****
  /* Declarations for C++ name lookup routines.
!    Copyright (C) 2003, 2004 Free Software Foundation, Inc.
     Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
  
  This file is part of GCC.
--- 1,5 ----
  /* Declarations for C++ name lookup routines.
!    Copyright (C) 2003, 2004, 2005  Free Software Foundation, Inc.
     Contributed by Gabriel Dos Reis <gdr@integrable-solutions.net>
  
  This file is part of GCC.
*************** extern void pop_from_top_level (void);
*** 299,305 ****
  extern void pop_everything (void);
  extern void keep_next_level (bool);
  extern bool is_ancestor (tree, tree);
! extern bool push_scope (tree);
  extern void pop_scope (tree);
  extern tree push_inner_scope (tree);
  extern void pop_inner_scope (tree, tree);
--- 299,305 ----
  extern void pop_everything (void);
  extern void keep_next_level (bool);
  extern bool is_ancestor (tree, tree);
! extern tree push_scope (tree);
  extern void pop_scope (tree);
  extern tree push_inner_scope (tree);
  extern void pop_inner_scope (tree, tree);
Index: cp/parser.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/parser.c,v
retrieving revision 1.300
diff -c -3 -p -r1.300 parser.c
*** cp/parser.c	3 Jan 2005 17:03:00 -0000	1.300
--- cp/parser.c	4 Jan 2005 16:22:54 -0000
***************
*** 1,5 ****
  /* C++ Parser.
!    Copyright (C) 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
     Written by Mark Mitchell <mark@codesourcery.com>.
  
     This file is part of GCC.
--- 1,6 ----
  /* C++ Parser.
!    Copyright (C) 2000, 2001, 2002, 2003, 2004,
!    2005  Free Software Foundation, Inc.
     Written by Mark Mitchell <mark@codesourcery.com>.
  
     This file is part of GCC.
*************** cp_parser_condition (cp_parser* parser)
*** 6231,6243 ****
  	 for sure.  */
        if (cp_parser_parse_definitely (parser))
  	{
! 	  bool pop_p;	
  
  	  /* Create the declaration.  */
  	  decl = start_decl (declarator, &type_specifiers,
  			     /*initialized_p=*/true,
  			     attributes, /*prefix_attributes=*/NULL_TREE,
! 			     &pop_p);
  	  /* Parse the assignment-expression.  */
  	  initializer = cp_parser_assignment_expression (parser);
  
--- 6232,6244 ----
  	 for sure.  */
        if (cp_parser_parse_definitely (parser))
  	{
! 	  tree pushed_scope;	
  
  	  /* Create the declaration.  */
  	  decl = start_decl (declarator, &type_specifiers,
  			     /*initialized_p=*/true,
  			     attributes, /*prefix_attributes=*/NULL_TREE,
! 			     &pushed_scope);
  	  /* Parse the assignment-expression.  */
  	  initializer = cp_parser_assignment_expression (parser);
  
*************** cp_parser_condition (cp_parser* parser)
*** 6247,6254 ****
  			  asm_specification,
  			  LOOKUP_ONLYCONVERTING);
  
! 	  if (pop_p)
! 	    pop_scope (DECL_CONTEXT (decl));
  
  	  return convert_from_reference (decl);
  	}
--- 6248,6255 ----
  			  asm_specification,
  			  LOOKUP_ONLYCONVERTING);
  
! 	  if (pushed_scope)
! 	    pop_scope (pushed_scope);
  
  	  return convert_from_reference (decl);
  	}
*************** cp_parser_conversion_function_id (cp_par
*** 7397,7403 ****
    tree saved_scope;
    tree saved_qualifying_scope;
    tree saved_object_scope;
!   bool pop_p = false;
  
    /* Look for the `operator' token.  */
    if (!cp_parser_require_keyword (parser, RID_OPERATOR, "`operator'"))
--- 7398,7404 ----
    tree saved_scope;
    tree saved_qualifying_scope;
    tree saved_object_scope;
!   tree pushed_scope = NULL_TREE;
  
    /* Look for the `operator' token.  */
    if (!cp_parser_require_keyword (parser, RID_OPERATOR, "`operator'"))
*************** cp_parser_conversion_function_id (cp_par
*** 7422,7433 ****
       In order to see that `I' is a type-name in the definition, we
       must be in the scope of `S'.  */
    if (saved_scope)
!     pop_p = push_scope (saved_scope);
    /* Parse the conversion-type-id.  */
    type = cp_parser_conversion_type_id (parser);
    /* Leave the scope of the class, if any.  */
!   if (pop_p)
!     pop_scope (saved_scope);
    /* Restore the saved scope.  */
    parser->scope = saved_scope;
    parser->qualifying_scope = saved_qualifying_scope;
--- 7423,7434 ----
       In order to see that `I' is a type-name in the definition, we
       must be in the scope of `S'.  */
    if (saved_scope)
!     pushed_scope = push_scope (saved_scope);
    /* Parse the conversion-type-id.  */
    type = cp_parser_conversion_type_id (parser);
    /* Leave the scope of the class, if any.  */
!   if (pushed_scope)
!     pop_scope (pushed_scope);
    /* Restore the saved scope.  */
    parser->scope = saved_scope;
    parser->qualifying_scope = saved_qualifying_scope;
*************** cp_parser_init_declarator (cp_parser* pa
*** 10426,10432 ****
    bool is_non_constant_init;
    int ctor_dtor_or_conv_p;
    bool friend_p;
!   bool pop_p = false;
  
    /* Gather the attributes that were provided with the
       decl-specifiers.  */
--- 10427,10433 ----
    bool is_non_constant_init;
    int ctor_dtor_or_conv_p;
    bool friend_p;
!   tree pushed_scope = NULL;
  
    /* Gather the attributes that were provided with the
       decl-specifiers.  */
*************** cp_parser_init_declarator (cp_parser* pa
*** 10583,10594 ****
  	}
        decl = start_decl (declarator, decl_specifiers,
  			 is_initialized, attributes, prefix_attributes,
! 			 &pop_p);
      }
    else if (scope)
      /* Enter the SCOPE.  That way unqualified names appearing in the
         initializer will be looked up in SCOPE.  */
!     pop_p = push_scope (scope);
  
    /* Perform deferred access control checks, now that we know in which
       SCOPE the declared entity resides.  */
--- 10584,10595 ----
  	}
        decl = start_decl (declarator, decl_specifiers,
  			 is_initialized, attributes, prefix_attributes,
! 			 &pushed_scope);
      }
    else if (scope)
      /* Enter the SCOPE.  That way unqualified names appearing in the
         initializer will be looked up in SCOPE.  */
!     pushed_scope = push_scope (scope);
  
    /* Perform deferred access control checks, now that we know in which
       SCOPE the declared entity resides.  */
*************** cp_parser_init_declarator (cp_parser* pa
*** 10638,10647 ****
       declaration.  */
    if (member_p)
      {
!       if (pop_p)
  	{
! 	  pop_scope (scope);
! 	  pop_p = false;
  	}
        decl = grokfield (declarator, decl_specifiers,
  			initializer, /*asmspec=*/NULL_TREE,
--- 10639,10648 ----
       declaration.  */
    if (member_p)
      {
!       if (pushed_scope)
  	{
! 	  pop_scope (pushed_scope);
! 	  pushed_scope = false;
  	}
        decl = grokfield (declarator, decl_specifiers,
  			initializer, /*asmspec=*/NULL_TREE,
*************** cp_parser_init_declarator (cp_parser* pa
*** 10663,10671 ****
  			 `explicit' constructor cannot be used.  */
  		      ((is_parenthesized_init || !is_initialized)
  		     ? 0 : LOOKUP_ONLYCONVERTING));
-       if (pop_p)
- 	pop_scope (DECL_CONTEXT (decl));
      }
  
    /* Remember whether or not variables were initialized by
       constant-expressions.  */
--- 10664,10672 ----
  			 `explicit' constructor cannot be used.  */
  		      ((is_parenthesized_init || !is_initialized)
  		     ? 0 : LOOKUP_ONLYCONVERTING));
      }
+   if (!friend_p && pushed_scope)
+     pop_scope (pushed_scope);
  
    /* Remember whether or not variables were initialized by
       constant-expressions.  */
*************** cp_parser_direct_declarator (cp_parser* 
*** 10836,10842 ****
    bool saved_default_arg_ok_p = parser->default_arg_ok_p;
    bool saved_in_declarator_p = parser->in_declarator_p;
    bool first = true;
!   bool pop_p = false;
  
    while (true)
      {
--- 10837,10843 ----
    bool saved_default_arg_ok_p = parser->default_arg_ok_p;
    bool saved_in_declarator_p = parser->in_declarator_p;
    bool first = true;
!   tree pushed_scope = NULL_TREE;
  
    while (true)
      {
*************** cp_parser_direct_declarator (cp_parser* 
*** 11136,11142 ****
  	  if (scope)
  	    /* Any names that appear after the declarator-id for a
  	       member are looked up in the containing scope.  */
! 	    pop_p = push_scope (scope);
  	  parser->in_declarator_p = true;
  	  if ((ctor_dtor_or_conv_p && *ctor_dtor_or_conv_p)
  	      || (declarator && declarator->kind == cdk_id))
--- 11137,11143 ----
  	  if (scope)
  	    /* Any names that appear after the declarator-id for a
  	       member are looked up in the containing scope.  */
! 	    pushed_scope = push_scope (scope);
  	  parser->in_declarator_p = true;
  	  if ((ctor_dtor_or_conv_p && *ctor_dtor_or_conv_p)
  	      || (declarator && declarator->kind == cdk_id))
*************** cp_parser_direct_declarator (cp_parser* 
*** 11159,11166 ****
      cp_parser_error (parser, "expected declarator");
  
    /* If we entered a scope, we must exit it now.  */
!   if (pop_p)
!     pop_scope (scope);
  
    parser->default_arg_ok_p = saved_default_arg_ok_p;
    parser->in_declarator_p = saved_in_declarator_p;
--- 11160,11167 ----
      cp_parser_error (parser, "expected declarator");
  
    /* If we entered a scope, we must exit it now.  */
!   if (pushed_scope)
!     pop_scope (pushed_scope);
  
    parser->default_arg_ok_p = saved_default_arg_ok_p;
    parser->in_declarator_p = saved_in_declarator_p;
*************** cp_parser_class_specifier (cp_parser* pa
*** 12350,12357 ****
      {
        tree queue_entry;
        tree fn;
!       tree class_type;
!       bool pop_p;
  
        /* In a first pass, parse default arguments to the functions.
  	 Then, in a second pass, parse the bodies of the functions.
--- 12351,12358 ----
      {
        tree queue_entry;
        tree fn;
!       tree class_type = NULL_TREE;
!       tree pushed_scope = NULL_TREE;
  
        /* In a first pass, parse default arguments to the functions.
  	 Then, in a second pass, parse the bodies of the functions.
*************** cp_parser_class_specifier (cp_parser* pa
*** 12363,12370 ****
              };
  
           */
-       class_type = NULL_TREE;
-       pop_p = false;
        for (TREE_PURPOSE (parser->unparsed_functions_queues)
  	     = nreverse (TREE_PURPOSE (parser->unparsed_functions_queues));
  	   (queue_entry = TREE_PURPOSE (parser->unparsed_functions_queues));
--- 12364,12369 ----
*************** cp_parser_class_specifier (cp_parser* pa
*** 12376,12385 ****
  	     take care of them now.  */
  	  if (class_type != TREE_PURPOSE (queue_entry))
  	    {
! 	      if (pop_p)
! 		pop_scope (class_type);
  	      class_type = TREE_PURPOSE (queue_entry);
! 	      pop_p = push_scope (class_type);
  	    }
  	  /* Make sure that any template parameters are in scope.  */
  	  maybe_begin_member_template_processing (fn);
--- 12375,12384 ----
  	     take care of them now.  */
  	  if (class_type != TREE_PURPOSE (queue_entry))
  	    {
! 	      if (pushed_scope)
! 		pop_scope (pushed_scope);
  	      class_type = TREE_PURPOSE (queue_entry);
! 	      pushed_scope = push_scope (class_type);
  	    }
  	  /* Make sure that any template parameters are in scope.  */
  	  maybe_begin_member_template_processing (fn);
*************** cp_parser_class_specifier (cp_parser* pa
*** 12388,12395 ****
  	  /* Remove any template parameters from the symbol table.  */
  	  maybe_end_member_template_processing ();
  	}
!       if (pop_p)
! 	pop_scope (class_type);
        /* Now parse the body of the functions.  */
        for (TREE_VALUE (parser->unparsed_functions_queues)
  	     = nreverse (TREE_VALUE (parser->unparsed_functions_queues));
--- 12387,12394 ----
  	  /* Remove any template parameters from the symbol table.  */
  	  maybe_end_member_template_processing ();
  	}
!       if (pushed_scope)
! 	pop_scope (pushed_scope);
        /* Now parse the body of the functions.  */
        for (TREE_VALUE (parser->unparsed_functions_queues)
  	     = nreverse (TREE_VALUE (parser->unparsed_functions_queues));
*************** cp_parser_class_head (cp_parser* parser,
*** 12457,12463 ****
    bool qualified_p = false;
    bool invalid_nested_name_p = false;
    bool invalid_explicit_specialization_p = false;
!   bool pop_p = false;
    unsigned num_templates;
    tree bases;
  
--- 12456,12462 ----
    bool qualified_p = false;
    bool invalid_nested_name_p = false;
    bool invalid_explicit_specialization_p = false;
!   tree pushed_scope = NULL_TREE;
    unsigned num_templates;
    tree bases;
  
*************** cp_parser_class_head (cp_parser* parser,
*** 12675,12693 ****
      {
        type = TREE_TYPE (id);
        maybe_process_partial_specialization (type);
      }
!   else if (!nested_name_specifier)
!     {
!       /* If the class was unnamed, create a dummy name.  */
!       if (!id)
! 	id = make_anon_name ();
!       type = xref_tag (class_key, id, /*tag_scope=*/ts_current,
! 		       parser->num_template_parameter_lists);
!     }
!   else
      {
        tree class_type;
-       bool pop_p = false;
  
        /* Given:
  
--- 12674,12685 ----
      {
        type = TREE_TYPE (id);
        maybe_process_partial_specialization (type);
+       if (nested_name_specifier)
+ 	pushed_scope = push_scope (nested_name_specifier);
      }
!   else if (nested_name_specifier)
      {
        tree class_type;
  
        /* Given:
  
*************** cp_parser_class_head (cp_parser* parser,
*** 12713,12720 ****
        maybe_process_partial_specialization (TREE_TYPE (type));
        class_type = current_class_type;
        /* Enter the scope indicated by the nested-name-specifier.  */
!       if (nested_name_specifier)
! 	pop_p = push_scope (nested_name_specifier);
        /* Get the canonical version of this type.  */
        type = TYPE_MAIN_DECL (TREE_TYPE (type));
        if (PROCESSING_REAL_TEMPLATE_DECL_P ()
--- 12705,12711 ----
        maybe_process_partial_specialization (TREE_TYPE (type));
        class_type = current_class_type;
        /* Enter the scope indicated by the nested-name-specifier.  */
!       pushed_scope = push_scope (nested_name_specifier);
        /* Get the canonical version of this type.  */
        type = TYPE_MAIN_DECL (TREE_TYPE (type));
        if (PROCESSING_REAL_TEMPLATE_DECL_P ()
*************** cp_parser_class_head (cp_parser* parser,
*** 12729,12757 ****
  	}
        
        type = TREE_TYPE (type);
!       if (nested_name_specifier)
! 	{
! 	  *nested_name_specifier_p = true;
! 	  if (pop_p)
! 	    pop_scope (nested_name_specifier);
! 	}
      }
    /* Indicate whether this class was declared as a `class' or as a
       `struct'.  */
    if (TREE_CODE (type) == RECORD_TYPE)
      CLASSTYPE_DECLARED_CLASS (type) = (class_key == class_type);
    cp_parser_check_class_key (class_key, type);
  
!   /* Enter the scope containing the class; the names of base classes
!      should be looked up in that context.  For example, given:
  
         struct A { struct B {}; struct C; };
         struct A::C : B {};
  
       is valid.  */
-   if (nested_name_specifier)
-     pop_p = push_scope (nested_name_specifier);
- 
    bases = NULL_TREE;
  
    /* Get the list of base-classes, if there is one.  */
--- 12720,12750 ----
  	}
        
        type = TREE_TYPE (type);
!       *nested_name_specifier_p = true;
      }
+   else      /* The name is not a nested name.  */
+     {
+       /* If the class was unnamed, create a dummy name.  */
+       if (!id)
+ 	id = make_anon_name ();
+       type = xref_tag (class_key, id, /*tag_scope=*/ts_current,
+ 		       parser->num_template_parameter_lists);
+     }
+ 
    /* Indicate whether this class was declared as a `class' or as a
       `struct'.  */
    if (TREE_CODE (type) == RECORD_TYPE)
      CLASSTYPE_DECLARED_CLASS (type) = (class_key == class_type);
    cp_parser_check_class_key (class_key, type);
  
!   /* We will have entered the scope containing the class; the names of
!      base classes should be looked up in that context.  For example,
!      given:
  
         struct A { struct B {}; struct C; };
         struct A::C : B {};
  
       is valid.  */
    bases = NULL_TREE;
  
    /* Get the list of base-classes, if there is one.  */
*************** cp_parser_class_head (cp_parser* parser,
*** 12761,12772 ****
    /* Process the base classes.  */
    xref_basetypes (type, bases);
  
    /* Leave the scope given by the nested-name-specifier.  We will
       enter the class scope itself while processing the members.  */
!   if (pop_p)
!     pop_scope (nested_name_specifier);
  
-  done:
    if (invalid_explicit_specialization_p)
      {
        end_specialization ();
--- 12754,12765 ----
    /* Process the base classes.  */
    xref_basetypes (type, bases);
  
+  done:
    /* Leave the scope given by the nested-name-specifier.  We will
       enter the class scope itself while processing the members.  */
!   if (pushed_scope)
!     pop_scope (pushed_scope);
  
    if (invalid_explicit_specialization_p)
      {
        end_specialization ();
*************** cp_parser_lookup_name (cp_parser *parser
*** 14207,14213 ****
  	}
        else
  	{
! 	  bool pop_p = false;
  
  	  /* If PARSER->SCOPE is a dependent type, then it must be a
  	     class type, and we must not be checking dependencies;
--- 14200,14206 ----
  	}
        else
  	{
! 	  tree pushed_scope = NULL_TREE;
  
  	  /* If PARSER->SCOPE is a dependent type, then it must be a
  	     class type, and we must not be checking dependencies;
*************** cp_parser_lookup_name (cp_parser *parser
*** 14215,14221 ****
  	     that PARSER->SCOPE is not considered a dependent base by
  	     lookup_member, we must enter the scope here.  */
  	  if (dependent_p)
! 	    pop_p = push_scope (parser->scope);
  	  /* If the PARSER->SCOPE is a a template specialization, it
  	     may be instantiated during name lookup.  In that case,
  	     errors may be issued.  Even if we rollback the current
--- 14208,14214 ----
  	     that PARSER->SCOPE is not considered a dependent base by
  	     lookup_member, we must enter the scope here.  */
  	  if (dependent_p)
! 	    pushed_scope = push_scope (parser->scope);
  	  /* If the PARSER->SCOPE is a a template specialization, it
  	     may be instantiated during name lookup.  In that case,
  	     errors may be issued.  Even if we rollback the current
*************** cp_parser_lookup_name (cp_parser *parser
*** 14223,14230 ****
  	  decl = lookup_qualified_name (parser->scope, name, 
  					tag_type != none_type, 
  					/*complain=*/true);
! 	  if (pop_p)
! 	    pop_scope (parser->scope);
  	}
        parser->qualifying_scope = parser->scope;
        parser->object_scope = NULL_TREE;
--- 14216,14223 ----
  	  decl = lookup_qualified_name (parser->scope, name, 
  					tag_type != none_type, 
  					/*complain=*/true);
! 	  if (pushed_scope)
! 	    pop_scope (pushed_scope);
  	}
        parser->qualifying_scope = parser->scope;
        parser->object_scope = NULL_TREE;
*************** cp_parser_constructor_declarator_p (cp_p
*** 14600,14606 ****
  	  && !cp_parser_storage_class_specifier_opt (parser))
  	{
  	  tree type;
! 	  bool pop_p = false;
  	  unsigned saved_num_template_parameter_lists;
  
  	  /* Names appearing in the type-specifier should be looked up
--- 14593,14599 ----
  	  && !cp_parser_storage_class_specifier_opt (parser))
  	{
  	  tree type;
! 	  tree pushed_scope = NULL_TREE;
  	  unsigned saved_num_template_parameter_lists;
  
  	  /* Names appearing in the type-specifier should be looked up
*************** cp_parser_constructor_declarator_p (cp_p
*** 14620,14626 ****
  		      return false;
  		    }
  		}
! 	      pop_p = push_scope (type);
  	    }
  
  	  /* Inside the constructor parameter list, surrounding
--- 14613,14619 ----
  		      return false;
  		    }
  		}
! 	      pushed_scope = push_scope (type);
  	    }
  
  	  /* Inside the constructor parameter list, surrounding
*************** cp_parser_constructor_declarator_p (cp_p
*** 14641,14648 ****
  	    = saved_num_template_parameter_lists;
  
  	  /* Leave the scope of the class.  */
! 	  if (pop_p)
! 	    pop_scope (type);
  
  	  constructor_p = !cp_parser_error_occurred (parser);
  	}
--- 14634,14641 ----
  	    = saved_num_template_parameter_lists;
  
  	  /* Leave the scope of the class.  */
! 	  if (pushed_scope)
! 	    pop_scope (pushed_scope);
  
  	  constructor_p = !cp_parser_error_occurred (parser);
  	}
Index: cp/pt.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cp/pt.c,v
retrieving revision 1.962
diff -c -3 -p -r1.962 pt.c
*** cp/pt.c	23 Dec 2004 19:54:08 -0000	1.962
--- cp/pt.c	4 Jan 2005 16:23:20 -0000
***************
*** 1,6 ****
  /* Handle parameterized types (templates) for GNU C++.
     Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
!    2001, 2002, 2003, 2004  Free Software Foundation, Inc.
     Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
     Rewritten by Jason Merrill (jason@cygnus.com).
  
--- 1,6 ----
  /* Handle parameterized types (templates) for GNU C++.
     Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
!    2001, 2002, 2003, 2004, 2005  Free Software Foundation, Inc.
     Written by Ken Raeburn (raeburn@cygnus.com) while at Watchmaker Computing.
     Rewritten by Jason Merrill (jason@cygnus.com).
  
*************** instantiate_class_template (tree type)
*** 5578,5590 ****
      {
        tree pbase_binfo;
        tree context = TYPE_CONTEXT (type);
!       bool pop_p;
        int i;
  
        /* We must enter the scope containing the type, as that is where
  	 the accessibility of types named in dependent bases are
  	 looked up from.  */
!       pop_p = push_scope (context ? context : global_namespace);
    
        /* Substitute into each of the bases to determine the actual
  	 basetypes.  */
--- 5578,5590 ----
      {
        tree pbase_binfo;
        tree context = TYPE_CONTEXT (type);
!       tree pushed_scope;
        int i;
  
        /* We must enter the scope containing the type, as that is where
  	 the accessibility of types named in dependent bases are
  	 looked up from.  */
!       pushed_scope = push_scope (context ? context : global_namespace);
    
        /* Substitute into each of the bases to determine the actual
  	 basetypes.  */
*************** instantiate_class_template (tree type)
*** 5606,5613 ****
        /* The list is now in reverse order; correct that.  */
        base_list = nreverse (base_list);
  
!       if (pop_p)
! 	pop_scope (context ? context : global_namespace);
      }
    /* Now call xref_basetypes to set up all the base-class
       information.  */
--- 5606,5613 ----
        /* The list is now in reverse order; correct that.  */
        base_list = nreverse (base_list);
  
!       if (pushed_scope)
! 	pop_scope (pushed_scope);
      }
    /* Now call xref_basetypes to set up all the base-class
       information.  */
*************** resolve_typename_type (tree type, bool o
*** 12286,12292 ****
    tree name;
    tree decl;
    int quals;
!   bool pop_p;
  
    gcc_assert (TREE_CODE (type) == TYPENAME_TYPE);
  
--- 12286,12292 ----
    tree name;
    tree decl;
    int quals;
!   tree pushed_scope;
  
    gcc_assert (TREE_CODE (type) == TYPENAME_TYPE);
  
*************** resolve_typename_type (tree type, bool o
*** 12315,12321 ****
    /* Enter the SCOPE so that name lookup will be resolved as if we
       were in the class definition.  In particular, SCOPE will no
       longer be considered a dependent type.  */
!   pop_p = push_scope (scope);
    /* Look up the declaration.  */
    decl = lookup_member (scope, name, /*protect=*/0, /*want_type=*/true);
    /* Obtain the set of qualifiers applied to the TYPE.  */
--- 12315,12321 ----
    /* Enter the SCOPE so that name lookup will be resolved as if we
       were in the class definition.  In particular, SCOPE will no
       longer be considered a dependent type.  */
!   pushed_scope = push_scope (scope);
    /* Look up the declaration.  */
    decl = lookup_member (scope, name, /*protect=*/0, /*want_type=*/true);
    /* Obtain the set of qualifiers applied to the TYPE.  */
*************** resolve_typename_type (tree type, bool o
*** 12345,12352 ****
    if (type != error_mark_node && quals)
      type = cp_build_qualified_type (type, quals);
    /* Leave the SCOPE.  */
!   if (pop_p)
!     pop_scope (scope);
  
    return type;
  }
--- 12345,12352 ----
    if (type != error_mark_node && quals)
      type = cp_build_qualified_type (type, quals);
    /* Leave the SCOPE.  */
!   if (pushed_scope)
!     pop_scope (pushed_scope);
  
    return type;
  }
// Copyright (C) 2005 Free Software Foundation, Inc.
// Contributed by Nathan Sidwell 4 Jan 2005 <nathan@codesourcery.com>

// PR 19030: ICE
// Origin: Volker Reichelt <reichelt@gcc.gnu.org>

struct A;

namespace N
{
  struct A;
}

using namespace N;

int A::i; // { dg-error "not been declared|declared here" "" }
int A::i; // { dg-error "not been declared|redefinition of" "" }

namespace N
{
    struct C;
    struct C {};
}

class D : N::C {};

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