PR c++/80891 (#1)
authorNathan Sidwell <nathan@acm.org>
Mon, 29 May 2017 14:08:04 +0000 (14:08 +0000)
committerNathan Sidwell <nathan@gcc.gnu.org>
Mon, 29 May 2017 14:08:04 +0000 (14:08 +0000)
PR c++/80891 (#1)
* pt.c (most_specialized_instantiation): Cope with duplicate
instantiations.

PR c++/80891 (#1)
* g++.dg/lookup/pr80891-1.C: New.

From-SVN: r248573

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/lookup/pr80891-1.C [new file with mode: 0644]

index 67d86fa111445d7f36593d7155fa47c98ecd6126..d538c3eb6f2ff23cc249e57f8ce8db392e50907f 100644 (file)
@@ -1,5 +1,9 @@
 2017-05-29  Nathan Sidwell  <nathan@acm.org>
 
+       PR c++/80891 (#1)
+       * pt.c (most_specialized_instantiation): Cope with duplicate
+       instantiations.
+
        PR c++/80891 (#3)
        * cp-tree.h (build_min_nt_call_vec): Declare.
        * decl.c (build_offset_ref_call_from_tree): Call it.
index 9c423366102440840e71197842135d754a33b089..d3a0d7a9b8b5025e761d680c3afedd3c3cb52d7d 100644 (file)
@@ -21728,31 +21728,32 @@ most_specialized_instantiation (tree templates)
 
   champ = templates;
   for (fn = TREE_CHAIN (templates); fn; fn = TREE_CHAIN (fn))
-    {
-      int fate = more_specialized_inst (TREE_VALUE (champ), TREE_VALUE (fn));
-      if (fate == -1)
-       champ = fn;
-      else if (!fate)
-       {
-         /* Equally specialized, move to next function.  If there
-            is no next function, nothing's most specialized.  */
-         fn = TREE_CHAIN (fn);
+    if (TREE_VALUE (champ) != TREE_VALUE (fn))
+      {
+       int fate = more_specialized_inst (TREE_VALUE (champ), TREE_VALUE (fn));
+       if (fate == -1)
          champ = fn;
-         if (!fn)
-           break;
-       }
-    }
+       else if (!fate)
+         {
+           /* Equally specialized, move to next function.  If there
+              is no next function, nothing's most specialized.  */
+           fn = TREE_CHAIN (fn);
+           champ = fn;
+           if (!fn)
+             break;
+         }
+      }
 
   if (champ)
     /* Now verify that champ is better than everything earlier in the
        instantiation list.  */
-    for (fn = templates; fn != champ; fn = TREE_CHAIN (fn)) {
-      if (more_specialized_inst (TREE_VALUE (champ), TREE_VALUE (fn)) != 1)
-      {
-        champ = NULL_TREE;
-        break;
-      }
-    }
+    for (fn = templates; fn != champ; fn = TREE_CHAIN (fn))
+      if (TREE_VALUE (champ) != TREE_VALUE (fn)
+         && more_specialized_inst (TREE_VALUE (champ), TREE_VALUE (fn)) != 1)
+       {
+         champ = NULL_TREE;
+         break;
+       }
 
   processing_template_decl--;
 
index d8603f8a8a3815ab2d345e39c693bd47420eae02..98e06f923bf0d2ab8b2a5444c8d21cb134306ce3 100644 (file)
@@ -1,5 +1,8 @@
 2017-05-29  Nathan Sidwell  <nathan@acm.org>
 
+       PR c++/80891 (#1)
+       * g++.dg/lookup/pr80891-1.C: New.
+
        PR c++/80891 (#3)
        * g++.dg/lookup/pr80891-3.C: New.
 
diff --git a/gcc/testsuite/g++.dg/lookup/pr80891-1.C b/gcc/testsuite/g++.dg/lookup/pr80891-1.C
new file mode 100644 (file)
index 0000000..725ca19
--- /dev/null
@@ -0,0 +1,19 @@
+// PR c++/80891 part 1
+// std::endl is found via two paths and most_specialized_instantiation
+// gets confused.
+
+namespace std {
+  struct A {
+    void operator<<(A(A));
+  };
+  template <typename _CharT, typename _Traits> _CharT endl(_Traits);
+  A a;
+}
+
+using std::endl;
+
+void chi_squared_sample_sized()
+{
+  using namespace std;
+  a << endl;
+}