aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNathan Sidwell <nathan@codesourcery.com>2002-01-02 11:26:12 +0000
committerNathan Sidwell <nathan@gcc.gnu.org>2002-01-02 11:26:12 +0000
commit477558bf39db7da00236fc414e0ac53a5712f577 (patch)
tree6468788a0a2bf269f655b445382edae8341460f7
parentdbac42475ce3f4ccb864b15e25417fdee36245fc (diff)
downloadgcc-477558bf39db7da00236fc414e0ac53a5712f577.zip
gcc-477558bf39db7da00236fc414e0ac53a5712f577.tar.gz
gcc-477558bf39db7da00236fc414e0ac53a5712f577.tar.bz2
PR c++/5116, c++/764
cp: PR c++/5116, c++/764 * call.c (build_new_op): Make sure template class operands are instantiated. Simplify arglist construction. testsuite: * g++.dg/template/friend2.C: New test. From-SVN: r48463
-rw-r--r--gcc/cp/ChangeLog6
-rw-r--r--gcc/cp/call.c25
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/g++.dg/template/friend2.C60
4 files changed, 87 insertions, 8 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index b392e95..beaf19a 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ PR c++/5116, c++/764
+ * call.c (build_new_op): Make sure template class operands are
+ instantiated. Simplify arglist construction.
+
2001-12-29 Nathan Sidwell <nathan@codesourcery.com>
* call.c (build_user_type_conversion_1): Use my_friendly_assert
diff --git a/gcc/cp/call.c b/gcc/cp/call.c
index 865d1ef..6672119 100644
--- a/gcc/cp/call.c
+++ b/gcc/cp/call.c
@@ -1,6 +1,6 @@
/* Functions related to invoking methods and overloaded functions.
Copyright (C) 1987, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001 Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Contributed by Michael Tiemann (tiemann@cygnus.com) and
modified by Brendan Kehoe (brendan@cygnus.com).
@@ -3247,6 +3247,10 @@ build_new_op (code, flags, arg1, arg2, arg3)
if (TREE_CODE (arg1) == OFFSET_REF)
arg1 = resolve_offset_ref (arg1);
arg1 = convert_from_reference (arg1);
+ if (CLASS_TYPE_P (TREE_TYPE (arg1))
+ && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (arg1)))
+ /* Make sure the template type is instantiated now. */
+ instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (arg1)));
switch (code)
{
@@ -3269,12 +3273,18 @@ build_new_op (code, flags, arg1, arg2, arg3)
if (TREE_CODE (arg2) == OFFSET_REF)
arg2 = resolve_offset_ref (arg2);
arg2 = convert_from_reference (arg2);
+ if (CLASS_TYPE_P (TREE_TYPE (arg2))
+ && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (arg2)))
+ instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (arg2)));
}
if (arg3)
{
if (TREE_CODE (arg3) == OFFSET_REF)
arg3 = resolve_offset_ref (arg3);
arg3 = convert_from_reference (arg3);
+ if (CLASS_TYPE_P (TREE_TYPE (arg3))
+ && CLASSTYPE_TEMPLATE_INSTANTIATION (TREE_TYPE (arg3)))
+ instantiate_class_template (TYPE_MAIN_VARIANT (TREE_TYPE (arg3)));
}
if (code == COND_EXPR)
@@ -3293,13 +3303,12 @@ build_new_op (code, flags, arg1, arg2, arg3)
if (code == POSTINCREMENT_EXPR || code == POSTDECREMENT_EXPR)
arg2 = integer_zero_node;
- if (arg2 && arg3)
- arglist = tree_cons (NULL_TREE, arg1, tree_cons
- (NULL_TREE, arg2, build_tree_list (NULL_TREE, arg3)));
- else if (arg2)
- arglist = tree_cons (NULL_TREE, arg1, build_tree_list (NULL_TREE, arg2));
- else
- arglist = build_tree_list (NULL_TREE, arg1);
+ arglist = NULL_TREE;
+ if (arg3)
+ arglist = tree_cons (NULL_TREE, arg3, arglist);
+ if (arg2)
+ arglist = tree_cons (NULL_TREE, arg2, arglist);
+ arglist = tree_cons (NULL_TREE, arg1, arglist);
fns = lookup_function_nonclass (fnname, arglist);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index eb39eea..dc7029d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2002-01-02 Nathan Sidwell <nathan@codesourcery.com>
+
+ * g++.dg/template/friend2.C: New test.
+
2002-01-01 Hans-Peter Nilsson <hp@bitrange.com>
* gcc.dg/mmix-1.c: New test.
diff --git a/gcc/testsuite/g++.dg/template/friend2.C b/gcc/testsuite/g++.dg/template/friend2.C
new file mode 100644
index 0000000..de07518
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/friend2.C
@@ -0,0 +1,60 @@
+// { dg-do run }
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 31 Dec 2001 <nathan@codesourcery.com>
+
+// PR 5116 Failed to find friend in overload resolution
+
+int wrong;
+int right;
+
+struct Printer
+{
+ Printer &operator<< (bool a)
+ {
+ wrong++;
+
+ return *this;
+ }
+
+};
+
+struct Buggy {};
+
+template <typename T> struct Handle
+{
+ Handle(T* p) {}
+
+ operator bool() const { return true; }
+
+ friend Printer& operator<<(Printer& ostr, const Handle& r)
+ {
+ right++;
+
+ return ostr;
+
+ }
+};
+
+typedef Handle<Buggy> Buggy_h;
+
+Printer out;
+
+bool cmp (const Buggy_h& b1, const Buggy_h& b2)
+{
+ out << b1 << b2;
+ return false;
+}
+
+int main()
+{
+ Buggy o;
+
+ cmp (&o, &o);
+
+ if (wrong)
+ return 1;
+ if (right != 2)
+ return 2;
+ return 0;
+}