OSDN Git Service

cp:
authornathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Jan 2002 11:26:12 +0000 (11:26 +0000)
committernathan <nathan@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 2 Jan 2002 11:26:12 +0000 (11:26 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@48463 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/cp/ChangeLog
gcc/cp/call.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/template/friend2.C [new file with mode: 0644]

index b392e95..beaf19a 100644 (file)
@@ -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
index 865d1ef..6672119 100644 (file)
@@ -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);
 
index eb39eea..dc7029d 100644 (file)
@@ -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 (file)
index 0000000..de07518
--- /dev/null
@@ -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;
+}