aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>1999-04-06 14:38:08 +0000
committermmitchel <mmitchel@138bc75d-0d04-0410-961f-82ee72b054a4>1999-04-06 14:38:08 +0000
commit96776925c513fd37753107ee345b15838aa9579b (patch)
tree526f3d6032e3d948ddc953c50478e9af7f1575bc
parentc947e6d56ec065aaca9bfb54d6c56bec7880dbdc (diff)
* cp-tree.h (BASELINK_P): New macro.
(SET_BASELINK_P): Likewise. * init.c (build_member_call): Remove needless assignment in if statement. * search.c (lookup_field_r): Fix handling when we are looking specifically for a type; these are not hidden by functions and variables. (lookup_member): Use SET_BASELINK_P. * tree.c (is_overloaded_fn): Use BASELINK_P. (really_overloaed_fn): Likewise. (get_first_fn): Likewise. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@26219 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/cp/ChangeLog14
-rw-r--r--gcc/cp/cp-tree.h11
-rw-r--r--gcc/cp/init.c2
-rw-r--r--gcc/cp/search.c80
-rw-r--r--gcc/cp/tree.c25
-rw-r--r--gcc/testsuite/g++.old-deja/g++.other/crash9.C9
-rw-r--r--gcc/testsuite/g++.old-deja/g++.pt/crash33.C17
7 files changed, 97 insertions, 61 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index e5d86a99f05..5dd92144328 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,17 @@
+1999-04-06 Mark Mitchell <mark@codesourcery.com>
+
+ * cp-tree.h (BASELINK_P): New macro.
+ (SET_BASELINK_P): Likewise.
+ * init.c (build_member_call): Remove needless assignment in if
+ statement.
+ * search.c (lookup_field_r): Fix handling when we are looking
+ specifically for a type; these are not hidden by functions and
+ variables.
+ (lookup_member): Use SET_BASELINK_P.
+ * tree.c (is_overloaded_fn): Use BASELINK_P.
+ (really_overloaed_fn): Likewise.
+ (get_first_fn): Likewise.
+
1999-04-05 Mark Mitchell <mark@codesourcery.com>
* decl.c (lookup_name_current_level): Tweak, and improve
diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h
index 6d0b2735bd2..0ed7d750232 100644
--- a/gcc/cp/cp-tree.h
+++ b/gcc/cp/cp-tree.h
@@ -33,7 +33,7 @@ Boston, MA 02111-1307, USA. */
TREE_INDIRECT_USING (in NAMESPACE_DECL).
IDENTIFIER_MARKED (used by search routines).
LOCAL_BINDING_P (in CPLUS_BINDING)
- 1: IDENTIFIER_VIRTUAL_P.
+ 1: IDENTIFIER_VIRTUAL_P.
TI_PENDING_TEMPLATE_FLAG.
TEMPLATE_PARMS_FOR_INLINE.
DELETE_EXPR_USE_VEC (in DELETE_EXPR).
@@ -41,6 +41,7 @@ Boston, MA 02111-1307, USA. */
TYPE_USES_COMPLEX_INHERITANCE (in _TYPE).
C_DECLARED_LABEL_FLAG.
INHERITED_VALUE_BINDING_P (in CPLUS_BINDING)
+ BASELINK_P (in TREE_LIST)
2: IDENTIFIER_OPNAME_P.
BINFO_VBASE_MARKED.
BINFO_FIELDS_MARKED.
@@ -191,6 +192,14 @@ struct tree_overload
tree function;
};
+/* A `baselink' is a TREE_LIST whose TREE_PURPOSE is a BINFO
+ indicating a particular base class, and whose TREE_VALUE is a
+ (possibly overloaded) function from that base class. */
+#define BASELINK_P(NODE) \
+ (TREE_CODE ((NODE)) == TREE_LIST && TREE_LANG_FLAG_1 ((NODE)))
+#define SET_BASELINK_P(NODE) \
+ (TREE_LANG_FLAG_1 ((NODE)) = 1)
+
#define WRAPPER_PTR(NODE) (((struct tree_wrapper*)NODE)->u.ptr)
#define WRAPPER_INT(NODE) (((struct tree_wrapper*)NODE)->u.i)
diff --git a/gcc/cp/init.c b/gcc/cp/init.c
index 06262036715..2769765ef63 100644
--- a/gcc/cp/init.c
+++ b/gcc/cp/init.c
@@ -1443,7 +1443,7 @@ build_member_call (type, name, parmlist)
if (method_name == constructor_name (type)
|| method_name == constructor_name_full (type))
return build_functional_cast (type, parmlist);
- if ((t = lookup_fnfields (basetype_path, method_name, 0)))
+ if (lookup_fnfields (basetype_path, method_name, 0))
return build_method_call (decl,
TREE_CODE (name) == TEMPLATE_ID_EXPR
? name : method_name,
diff --git a/gcc/cp/search.c b/gcc/cp/search.c
index 99e25a84a15..7a13a9f1e0d 100644
--- a/gcc/cp/search.c
+++ b/gcc/cp/search.c
@@ -1207,17 +1207,20 @@ lookup_field_r (binfo, data)
{
struct lookup_field_info *lfi = (struct lookup_field_info *) data;
tree type = BINFO_TYPE (binfo);
- tree nval;
- int idx;
+ tree nval = NULL_TREE;
int from_dep_base_p;
/* First, look for a function. There can't be a function and a data
member with the same name, and if there's a function and a type
with the same name, the type is hidden by the function. */
- idx = lookup_fnfields_here (type, lfi->name);
- if (idx >= 0)
- nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);
- else
+ if (!lfi->want_type)
+ {
+ int idx = lookup_fnfields_here (type, lfi->name);
+ if (idx >= 0)
+ nval = TREE_VEC_ELT (CLASSTYPE_METHOD_VEC (type), idx);
+ }
+
+ if (!nval)
/* Look for a data member or type. */
nval = lookup_field_1 (type, lfi->name);
@@ -1226,6 +1229,17 @@ lookup_field_r (binfo, data)
if (!nval)
return NULL_TREE;
+ /* If we're looking up a type (as with an elaborated type specifier)
+ we ignore all non-types we find. */
+ if (lfi->want_type && TREE_CODE (nval) != TYPE_DECL)
+ {
+ nval = purpose_member (lfi->name, CLASSTYPE_TAGS (type));
+ if (nval)
+ nval = TYPE_MAIN_DECL (TREE_VALUE (nval));
+ else
+ return NULL_TREE;
+ }
+
/* You must name a template base class with a template-id. */
if (!same_type_p (type, lfi->type)
&& template_self_reference_p (type, nval))
@@ -1285,41 +1299,24 @@ lookup_field_r (binfo, data)
}
else
{
- /* The new lookup is the best we've got so far. Verify that
- it's the kind of thing we're looking for. */
- if (lfi->want_type && TREE_CODE (nval) != TYPE_DECL)
+ /* If the thing we're looking for is a virtual base class, then
+ we know we've got what we want at this point; there's no way
+ to get an ambiguity. */
+ if (VBASE_NAME_P (lfi->name))
{
- nval = purpose_member (lfi->name, CLASSTYPE_TAGS (type));
- if (nval)
- {
- nval = TYPE_MAIN_DECL (TREE_VALUE (nval));
- if (!same_type_p (type, lfi->type)
- && template_self_reference_p (type, nval))
- nval = NULL_TREE;
- }
+ lfi->rval = nval;
+ return nval;
}
- if (nval)
- {
- /* If the thing we're looking for is a virtual base class,
- then we know we've got what we want at this point;
- there's no way to get an ambiguity. */
- if (VBASE_NAME_P (lfi->name))
- {
- lfi->rval = nval;
- return nval;
- }
-
- if (from_dep_base_p && TREE_CODE (nval) != TYPE_DECL
- /* We need to return a member template class so we can
- define partial specializations. Is there a better
- way? */
- && !DECL_CLASS_TEMPLATE_P (nval))
- /* The thing we're looking for isn't a type, so the implicit
- typename extension doesn't apply, so we just pretend we
- didn't find anything. */
- return NULL_TREE;
- }
+ if (from_dep_base_p && TREE_CODE (nval) != TYPE_DECL
+ /* We need to return a member template class so we can
+ define partial specializations. Is there a better
+ way? */
+ && !DECL_CLASS_TEMPLATE_P (nval))
+ /* The thing we're looking for isn't a type, so the implicit
+ typename extension doesn't apply, so we just pretend we
+ didn't find anything. */
+ return NULL_TREE;
lfi->rval = nval;
lfi->from_dep_base_p = from_dep_base_p;
@@ -1444,8 +1441,11 @@ lookup_member (xbasetype, name, protect, want_type)
name, name,
TREE_TYPE (rval)));
- if (rval && is_overloaded_fn (rval))
- rval = scratch_tree_cons (basetype_path, rval, NULL_TREE);
+ if (rval && is_overloaded_fn (rval))
+ {
+ rval = scratch_tree_cons (basetype_path, rval, NULL_TREE);
+ SET_BASELINK_P (rval);
+ }
return rval;
}
diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c
index 96d9cbd72bd..44e958f064d 100644
--- a/gcc/cp/tree.c
+++ b/gcc/cp/tree.c
@@ -1223,21 +1223,9 @@ int
is_overloaded_fn (x)
tree x;
{
- /* XXX A baselink is also considered an overloaded function.
- As is a placeholder from push_class_decls.
- As is an expression like X::f. */
- if (TREE_CODE (x) == TREE_LIST)
- {
- if (TREE_PURPOSE (x) == error_mark_node)
- {
- x = TREE_VALUE (x);
- my_friendly_assert (TREE_CODE (x) == TREE_LIST, 981121);
- }
- my_friendly_assert (TREE_CODE (TREE_PURPOSE (x)) == TREE_VEC
- || TREE_CODE (TREE_PURPOSE (x)) == IDENTIFIER_NODE,
- 388);
- x = TREE_VALUE (x);
- }
+ /* A baselink is also considered an overloaded function. */
+ if (BASELINK_P (x))
+ x = TREE_VALUE (x);
return (TREE_CODE (x) == FUNCTION_DECL
|| TREE_CODE (x) == TEMPLATE_ID_EXPR
|| DECL_FUNCTION_TEMPLATE_P (x)
@@ -1248,9 +1236,8 @@ int
really_overloaded_fn (x)
tree x;
{
- /* A baselink is also considered an overloaded function.
- This might also be an ambiguous class member. */
- if (TREE_CODE (x) == TREE_LIST)
+ /* A baselink is also considered an overloaded function. */
+ if (BASELINK_P (x))
x = TREE_VALUE (x);
return (TREE_CODE (x) == OVERLOAD
&& (TREE_CHAIN (x) != NULL_TREE
@@ -1263,7 +1250,7 @@ get_first_fn (from)
{
my_friendly_assert (is_overloaded_fn (from), 9);
/* A baselink is also considered an overloaded function. */
- if (TREE_CODE (from) == TREE_LIST)
+ if (BASELINK_P (from))
from = TREE_VALUE (from);
return OVL_CURRENT (from);
}
diff --git a/gcc/testsuite/g++.old-deja/g++.other/crash9.C b/gcc/testsuite/g++.old-deja/g++.other/crash9.C
new file mode 100644
index 00000000000..d3c23977abf
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.other/crash9.C
@@ -0,0 +1,9 @@
+// Build don't link:
+// Origin: Jason Merrill <jason@cygnus.com>
+
+struct A { };
+struct B : public A
+{
+ int A;
+};
+struct C : public B { };
diff --git a/gcc/testsuite/g++.old-deja/g++.pt/crash33.C b/gcc/testsuite/g++.old-deja/g++.pt/crash33.C
new file mode 100644
index 00000000000..bc7dcf5c4c7
--- /dev/null
+++ b/gcc/testsuite/g++.old-deja/g++.pt/crash33.C
@@ -0,0 +1,17 @@
+// Build don't link:
+// Origin: Theodore Papadopoulo <Theodore.Papadopoulo@sophia.inria.fr>
+
+class A {
+public:
+ template <class T> T& f(T& t) const;
+};
+
+class B {
+public:
+ template <class T> T& f(T& t) const;
+};
+
+class C: public A,B {
+public:
+ template <class T> T& f(T& t) const;
+};