re PR c++/7647 (ICE when data member has the name of the enclosing class)

PR c++/7647
	* decl.c (grokdeclarator): Tidy, slightly.
	* search.c (lookup_field_1): Add want_type parameter.
	(lookup_field_r): Adjust call to lookup_field_1.

	PR c++/7647
	* g++.dg/lookup-class-member-2.C: New test.

From-SVN: r65057
This commit is contained in:
Mark Mitchell 2003-03-30 22:30:54 +00:00 committed by Mark Mitchell
parent ececa17224
commit c717c5af27
5 changed files with 55 additions and 25 deletions

View File

@ -1,3 +1,10 @@
2003-03-30 Mark Mitchell <mark@codesourcery.com>
PR c++/7647
* decl.c (grokdeclarator): Tidy, slightly.
* search.c (lookup_field_1): Add want_type parameter.
(lookup_field_r): Adjust call to lookup_field_1.
2003-03-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
* Make-lang.in (cp/name-lookup.o): Add more dependencies.

View File

@ -11551,18 +11551,15 @@ grokdeclarator (tree declarator,
return void_type_node;
}
/* 9.2p13 [class.mem] */
if (constructor_name_p (declarator, current_class_type)
/* The standard does not allow non-static data members
here either, but we agreed at the 10/99 meeting
to change that in TC 1 so that they are allowed in
classes with no user-defined constructors. */
&& staticp)
pedwarn ("ISO C++ forbids static data member `%D' with same name as enclosing class",
declarator);
if (staticp)
{
/* [class.mem] forbids static data members with the
same name as the enclosing class. Non-static data
members are checked in check_field_decls. */
if (constructor_name_p (declarator, current_class_type))
pedwarn ("ISO C++ forbids static data member `%D' with same name as enclosing class",
declarator);
/* C++ allows static class members. All other work
for this is done by grokfield. */
decl = build_lang_decl (VAR_DECL, declarator, type);

View File

@ -81,7 +81,7 @@ struct vbase_info
tree inits;
};
static tree lookup_field_1 (tree, tree);
static tree lookup_field_1 (tree, tree, bool);
static tree dfs_check_overlap (tree, void *);
static tree dfs_no_overlap_yet (tree, int, void *);
static base_kind lookup_base_r (tree, tree, base_access,
@ -420,17 +420,18 @@ get_dynamic_cast_base_type (tree subtype, tree target)
return offset;
}
/* Search for a member with name NAME in a multiple inheritance lattice
specified by TYPE. If it does not exist, return NULL_TREE.
/* Search for a member with name NAME in a multiple inheritance
lattice specified by TYPE. If it does not exist, return NULL_TREE.
If the member is ambiguously referenced, return `error_mark_node'.
Otherwise, return the FIELD_DECL. */
Otherwise, return a DECL with the indicated name. If WANT_TYPE is
true, type declarations are preferred. */
/* Do a 1-level search for NAME as a member of TYPE. The caller must
figure out whether it can access this field. (Since it is only one
level, this is reasonable.) */
static tree
lookup_field_1 (tree type, tree name)
lookup_field_1 (tree type, tree name, bool want_type)
{
register tree field;
@ -467,14 +468,24 @@ lookup_field_1 (tree type, tree name)
lo = i + 1;
else
{
field = NULL_TREE;
/* We might have a nested class and a field with the
same name; we sorted them appropriately via
field_decl_cmp, so just look for the last field with
this name. */
while (i + 1 < hi
&& DECL_NAME (fields[i+1]) == name)
++i;
return fields[i];
while (true)
{
if (!want_type
|| TREE_CODE (fields[i]) == TYPE_DECL
|| DECL_CLASS_TEMPLATE_P (fields[i]))
field = fields[i];
if (i + 1 == hi || DECL_NAME (fields[i+1]) != name)
break;
i++;
}
return field;
}
}
return NULL_TREE;
@ -485,7 +496,7 @@ lookup_field_1 (tree type, tree name)
#ifdef GATHER_STATISTICS
n_calls_lookup_field_1++;
#endif /* GATHER_STATISTICS */
while (field)
for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
{
#ifdef GATHER_STATISTICS
n_fields_searched++;
@ -494,7 +505,7 @@ lookup_field_1 (tree type, tree name)
if (DECL_NAME (field) == NULL_TREE
&& ANON_AGGR_TYPE_P (TREE_TYPE (field)))
{
tree temp = lookup_field_1 (TREE_TYPE (field), name);
tree temp = lookup_field_1 (TREE_TYPE (field), name, want_type);
if (temp)
return temp;
}
@ -504,10 +515,13 @@ lookup_field_1 (tree type, tree name)
to return a USING_DECL, and the rest of the compiler can't
handle it. Once the class is defined, these are purged
from TYPE_FIELDS anyhow; see handle_using_decl. */
;
else if (DECL_NAME (field) == name)
continue;
if (DECL_NAME (field) == name
&& (!want_type
|| TREE_CODE (field) == TYPE_DECL
|| DECL_CLASS_TEMPLATE_P (field)))
return field;
field = TREE_CHAIN (field);
}
/* Not found. */
if (name == vptr_identifier)
@ -1079,7 +1093,7 @@ lookup_field_r (tree binfo, void *data)
if (!nval)
/* Look for a data member or type. */
nval = lookup_field_1 (type, lfi->name);
nval = lookup_field_1 (type, lfi->name, lfi->want_type);
/* If there is no declaration with the indicated name in this type,
then there's nothing to do. */

View File

@ -1,3 +1,8 @@
2003-03-30 Mark Mitchell <mark@codesourcery.com>
PR c++/7647
* g++.dg/lookup-class-member-2.C: New test.
2003-03-30 Glen Nakamura <glen@imodulo.com>
* gcc.dg/20030324-1.c: Add comments and abort if test fails.

View File

@ -0,0 +1,7 @@
template <typename T> struct A
{
void foo () const {}
char A;
};
void bar() { A<void>().foo(); }