Commit c717c5af by Mark Mitchell Committed by Mark Mitchell

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
parent ececa172
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> 2003-03-30 Gabriel Dos Reis <gdr@integrable-solutions.net>
* Make-lang.in (cp/name-lookup.o): Add more dependencies. * Make-lang.in (cp/name-lookup.o): Add more dependencies.
......
...@@ -11551,18 +11551,15 @@ grokdeclarator (tree declarator, ...@@ -11551,18 +11551,15 @@ grokdeclarator (tree declarator,
return void_type_node; return void_type_node;
} }
/* 9.2p13 [class.mem] */ if (staticp)
if (constructor_name_p (declarator, current_class_type) {
/* The standard does not allow non-static data members /* [class.mem] forbids static data members with the
here either, but we agreed at the 10/99 meeting same name as the enclosing class. Non-static data
to change that in TC 1 so that they are allowed in members are checked in check_field_decls. */
classes with no user-defined constructors. */ if (constructor_name_p (declarator, current_class_type))
&& staticp)
pedwarn ("ISO C++ forbids static data member `%D' with same name as enclosing class", pedwarn ("ISO C++ forbids static data member `%D' with same name as enclosing class",
declarator); declarator);
if (staticp)
{
/* C++ allows static class members. All other work /* C++ allows static class members. All other work
for this is done by grokfield. */ for this is done by grokfield. */
decl = build_lang_decl (VAR_DECL, declarator, type); decl = build_lang_decl (VAR_DECL, declarator, type);
......
...@@ -81,7 +81,7 @@ struct vbase_info ...@@ -81,7 +81,7 @@ struct vbase_info
tree inits; 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_check_overlap (tree, void *);
static tree dfs_no_overlap_yet (tree, int, void *); static tree dfs_no_overlap_yet (tree, int, void *);
static base_kind lookup_base_r (tree, tree, base_access, static base_kind lookup_base_r (tree, tree, base_access,
...@@ -420,17 +420,18 @@ get_dynamic_cast_base_type (tree subtype, tree target) ...@@ -420,17 +420,18 @@ get_dynamic_cast_base_type (tree subtype, tree target)
return offset; return offset;
} }
/* Search for a member with name NAME in a multiple inheritance lattice /* Search for a member with name NAME in a multiple inheritance
specified by TYPE. If it does not exist, return NULL_TREE. lattice specified by TYPE. If it does not exist, return NULL_TREE.
If the member is ambiguously referenced, return `error_mark_node'. 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 /* 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 figure out whether it can access this field. (Since it is only one
level, this is reasonable.) */ level, this is reasonable.) */
static tree static tree
lookup_field_1 (tree type, tree name) lookup_field_1 (tree type, tree name, bool want_type)
{ {
register tree field; register tree field;
...@@ -467,14 +468,24 @@ lookup_field_1 (tree type, tree name) ...@@ -467,14 +468,24 @@ lookup_field_1 (tree type, tree name)
lo = i + 1; lo = i + 1;
else else
{ {
field = NULL_TREE;
/* We might have a nested class and a field with the /* We might have a nested class and a field with the
same name; we sorted them appropriately via same name; we sorted them appropriately via
field_decl_cmp, so just look for the last field with field_decl_cmp, so just look for the last field with
this name. */ this name. */
while (i + 1 < hi while (true)
&& DECL_NAME (fields[i+1]) == name) {
++i; if (!want_type
return fields[i]; || 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; return NULL_TREE;
...@@ -485,7 +496,7 @@ lookup_field_1 (tree type, tree name) ...@@ -485,7 +496,7 @@ lookup_field_1 (tree type, tree name)
#ifdef GATHER_STATISTICS #ifdef GATHER_STATISTICS
n_calls_lookup_field_1++; n_calls_lookup_field_1++;
#endif /* GATHER_STATISTICS */ #endif /* GATHER_STATISTICS */
while (field) for (field = TYPE_FIELDS (type); field; field = TREE_CHAIN (field))
{ {
#ifdef GATHER_STATISTICS #ifdef GATHER_STATISTICS
n_fields_searched++; n_fields_searched++;
...@@ -494,7 +505,7 @@ lookup_field_1 (tree type, tree name) ...@@ -494,7 +505,7 @@ lookup_field_1 (tree type, tree name)
if (DECL_NAME (field) == NULL_TREE if (DECL_NAME (field) == NULL_TREE
&& ANON_AGGR_TYPE_P (TREE_TYPE (field))) && 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) if (temp)
return temp; return temp;
} }
...@@ -504,10 +515,13 @@ lookup_field_1 (tree type, tree name) ...@@ -504,10 +515,13 @@ lookup_field_1 (tree type, tree name)
to return a USING_DECL, and the rest of the compiler can't to return a USING_DECL, and the rest of the compiler can't
handle it. Once the class is defined, these are purged handle it. Once the class is defined, these are purged
from TYPE_FIELDS anyhow; see handle_using_decl. */ from TYPE_FIELDS anyhow; see handle_using_decl. */
; continue;
else if (DECL_NAME (field) == name)
if (DECL_NAME (field) == name
&& (!want_type
|| TREE_CODE (field) == TYPE_DECL
|| DECL_CLASS_TEMPLATE_P (field)))
return field; return field;
field = TREE_CHAIN (field);
} }
/* Not found. */ /* Not found. */
if (name == vptr_identifier) if (name == vptr_identifier)
...@@ -1079,7 +1093,7 @@ lookup_field_r (tree binfo, void *data) ...@@ -1079,7 +1093,7 @@ lookup_field_r (tree binfo, void *data)
if (!nval) if (!nval)
/* Look for a data member or type. */ /* 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, /* If there is no declaration with the indicated name in this type,
then there's nothing to do. */ then there's nothing to do. */
......
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> 2003-03-30 Glen Nakamura <glen@imodulo.com>
* gcc.dg/20030324-1.c: Add comments and abort if test fails. * gcc.dg/20030324-1.c: Add comments and abort if test fails.
......
template <typename T> struct A
{
void foo () const {}
char A;
};
void bar() { A<void>().foo(); }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment