aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Mitchell <mark@codesourcery.com>2003-03-30 22:30:54 +0000
committerMark Mitchell <mmitchel@gcc.gnu.org>2003-03-30 22:30:54 +0000
commitc717c5af279f31b4e469f01469d17a7720c56d54 (patch)
treec662afcd8166ca7d165f9e1bd25793596732a999
parentececa172241797d42e5f98652b54fdd0d00e23d9 (diff)
downloadgcc-c717c5af279f31b4e469f01469d17a7720c56d54.zip
gcc-c717c5af279f31b4e469f01469d17a7720c56d54.tar.gz
gcc-c717c5af279f31b4e469f01469d17a7720c56d54.tar.bz2
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
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/decl.c17
-rw-r--r--gcc/cp/search.c44
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/g++.dg/lookup/class-member-2.C7
5 files changed, 55 insertions, 25 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index bd93d28..93df69d 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -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.
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index 602a116..e2dc018 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -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);
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 7cc1fa1..9fc8431 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -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. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index dff3af3..1eb2836 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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.
diff --git a/gcc/testsuite/g++.dg/lookup/class-member-2.C b/gcc/testsuite/g++.dg/lookup/class-member-2.C
new file mode 100644
index 0000000..8e4dbe7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/lookup/class-member-2.C
@@ -0,0 +1,7 @@
+template <typename T> struct A
+{
+ void foo () const {}
+ char A;
+};
+
+void bar() { A<void>().foo(); }