This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[C++] Fix 19030 - ICE
- From: Nathan Sidwell <nathan at codesourcery dot com>
- To: GCC Patches <gcc-patches at gcc dot gnu dot org>
- Date: Wed, 05 Jan 2005 10:03:08 +0000
- Subject: [C++] Fix 19030 - ICE
- Organization: Codesourcery LLC
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 {};