PR c++/71784 - ICE with ref-qualifier and explicit specialization.
authorJason Merrill <jason@redhat.com>
Wed, 28 Feb 2018 21:34:07 +0000 (16:34 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Wed, 28 Feb 2018 21:34:07 +0000 (16:34 -0500)
* pt.c (determine_specialization): Check ref-qualifier.

From-SVN: r258085

gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/g++.dg/cpp0x/ref-qual18.C [new file with mode: 0644]

index 40d7f87..be9b3fd 100644 (file)
@@ -1,3 +1,8 @@
+2018-02-28  Jason Merrill  <jason@redhat.com>
+
+       PR c++/71784 - ICE with ref-qualifier and explicit specialization.
+       * pt.c (determine_specialization): Check ref-qualifier.
+
 2018-02-28  Jakub Jelinek  <jakub@redhat.com>
 
        PR c++/84609
index 507675b..7345119 100644 (file)
@@ -2163,10 +2163,17 @@ determine_specialization (tree template_id,
             that the const qualification is the same.  Since
             get_bindings does not try to merge the "this" parameter,
             we must do the comparison explicitly.  */
-         if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
-             && !same_type_p (TREE_VALUE (fn_arg_types),
-                              TREE_VALUE (decl_arg_types)))
-           continue;
+         if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn))
+           {
+             if (!same_type_p (TREE_VALUE (fn_arg_types),
+                               TREE_VALUE (decl_arg_types)))
+               continue;
+
+             /* And the ref-qualification.  */
+             if (type_memfn_rqual (TREE_TYPE (decl))
+                 != type_memfn_rqual (TREE_TYPE (fn)))
+               continue;
+           }
 
          /* Skip the "this" parameter and, for constructors of
             classes with virtual bases, the VTT parameter.  A
@@ -2277,6 +2284,11 @@ determine_specialization (tree template_id,
                         decl_arg_types))
             continue;
 
+         if (DECL_NONSTATIC_MEMBER_FUNCTION_P (fn)
+             && (type_memfn_rqual (TREE_TYPE (decl))
+                 != type_memfn_rqual (TREE_TYPE (fn))))
+           continue;
+
           // If the deduced arguments do not satisfy the constraints,
           // this is not a candidate.
           if (flag_concepts && !constraints_satisfied_p (fn))
diff --git a/gcc/testsuite/g++.dg/cpp0x/ref-qual18.C b/gcc/testsuite/g++.dg/cpp0x/ref-qual18.C
new file mode 100644 (file)
index 0000000..aaa00b9
--- /dev/null
@@ -0,0 +1,18 @@
+// PR c++/71784
+// { dg-do compile { target c++11 } }
+
+template<typename T> struct A {
+  template<typename U> void f(U const&) & { }
+  template<typename U> void f(U const&) && { }
+};
+
+template void A<int>::f<int>(int const&) &;
+template void A<float>::f<int>(int const&) &&;
+
+template<typename T> struct B {
+  void f(int const&) & { }
+  void f(int const&) && { }
+};
+
+template void B<int>::f(int const&) &;
+template void B<float>::f(int const&) &&;