PR c++/5116, c++/764
authorNathan Sidwell <nathan@codesourcery.com>
Thu, 26 Dec 2002 12:23:11 +0000 (12:23 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Thu, 26 Dec 2002 12:23:11 +0000 (12:23 +0000)
cp:
        PR c++/5116, c++/764
        * call.c (build_new_op): Make sure template class operands are
        instantiated.
testsuite:
        * g++.dg/template/friend10.C: New test.
        * g++.dg/template/conv5.C: New test.

From-SVN: r60514

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

index 3f4c1d0319bb848b93b8b587a8ca5d049bbfd8b4..2291b733b5893fd168731c45fee6e7c97cbc7c2d 100644 (file)
@@ -1,3 +1,9 @@
+2002-12-26  Nathan Sidwell  <nathan@codesourcery.com>
+
+       PR c++/5116, c++/764
+       * call.c (build_new_op): Make sure template class operands are
+       instantiated.
+
 2002-12-24  Nathan Sidwell  <nathan@codesourcery.com>
 
        PR C++/7964
index 088cc1e46e5ff08116457d56e30d06f0444bad28..919087059d83e13871b361011298755f279aad86 100644 (file)
@@ -3343,6 +3343,10 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree 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)
     {
@@ -3365,12 +3369,18 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree 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)
index 8196168626b8bc36083b2c0e573f16e186463e56..a68ab21957b7fd06baa06f566d0a06b6750ca151 100644 (file)
@@ -1,3 +1,8 @@
+2002-12-26  Nathan Sidwell  <nathan@codesourcery.com>
+
+       * g++.dg/template/friend10.C: New test.
+       * g++.dg/template/conv5.C: New test.
+
 2002-12-24  Nathan Sidwell  <nathan@codesourcery.com>
        
        * g++.dg/lookup/scoped3.C: New test.
diff --git a/gcc/testsuite/g++.dg/template/conv5.C b/gcc/testsuite/g++.dg/template/conv5.C
new file mode 100644 (file)
index 0000000..8083543
--- /dev/null
@@ -0,0 +1,22 @@
+// { dg-do compile }
+
+// Copyright (C) 2001 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 26 Dec 2002 <nathan@codesourcery.com>
+
+// PR 764. Failed to find friend in overload resolution
+
+template <class T>
+struct S
+{
+  friend bool operator== (const S&, const S&) {
+    return true;
+  }
+};
+
+int main ()
+{
+   // S<int> s;
+  
+  const S<int> *p = 0;
+  *p == *p; // error
+}
diff --git a/gcc/testsuite/g++.dg/template/friend10.C b/gcc/testsuite/g++.dg/template/friend10.C
new file mode 100644 (file)
index 0000000..cab5e34
--- /dev/null
@@ -0,0 +1,45 @@
+// { dg-do run }
+
+// Copyright (C) 2002 Free Software Foundation, Inc.
+// Contributed by Nathan Sidwell 24 Dec 2002 <nathan@codesourcery.com>
+
+// PR 5116. template instantiation can add a friend into a namespace,
+// and thus change overload resolution.
+
+#include <iostream>
+
+static int right;
+static int wrong;
+
+struct Buggy {};
+
+template <typename T>struct Handle
+{
+  Handle(T* p) {}
+  
+  operator bool() const { wrong++; return true; }
+  
+  friend std::ostream& operator<<(std::ostream& ostr, const Handle& r)
+  {
+    right++;
+    
+    return ostr << "in operator<<(ostream&, const Handle&)";
+  }
+};
+
+typedef Handle<Buggy>     Buggy_h;
+
+bool cmp (const Buggy_h& b1, const Buggy_h& b2)
+{
+  std::cout << b1 << " " << b2 << std::endl;
+  return false;
+}
+
+int main()
+{
+  Buggy o;
+  
+  cmp (&o, &o);
+
+  return !(right == 2 && !wrong);
+}