In this testcase the problem was that we end up with a non-ref-qualified type which has a ref-qualified TYPE_CANONICAL because the middle-end check_qualified_type doesn't know about ref-qualifiers. So apply_memfn_quals needs to set it up on TYPE_CANONICAL as well.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 478c1d31bb46a032d07839c4d1679907a1b5bcf8
Author: Jason Merrill <ja...@redhat.com>
Date:   Mon Dec 15 14:31:12 2014 -0500

    	PR c++/64297
    	* typeck.c (apply_memfn_quals): Correct wrong TYPE_CANONICAL.

diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index 7b39816..9368b49 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -8945,6 +8945,12 @@ apply_memfn_quals (tree type, cp_cv_quals memfn_quals, cp_ref_qualifier rqual)
   /* This should really have a different TYPE_MAIN_VARIANT, but that gets
      complex.  */
   tree result = build_qualified_type (type, memfn_quals);
+  if (tree canon = TYPE_CANONICAL (result))
+    if (canon != result)
+      /* check_qualified_type doesn't check the ref-qualifier, so make sure
+	 TYPE_CANONICAL is correct.  */
+      TYPE_CANONICAL (result)
+	= build_ref_qualified_type (canon, type_memfn_rqual (result));
   result = build_exception_variant (result, TYPE_RAISES_EXCEPTIONS (type));
   return build_ref_qualified_type (result, rqual);
 }
diff --git a/gcc/testsuite/g++.dg/cpp0x/ref-qual16.C b/gcc/testsuite/g++.dg/cpp0x/ref-qual16.C
new file mode 100644
index 0000000..7409418
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/ref-qual16.C
@@ -0,0 +1,13 @@
+// PR c++/64297
+// { dg-do compile { target c++11 } }
+
+struct A {
+  typedef int X;
+  template <int> X m_fn1() const;
+};
+template <typename> struct is_function {};
+is_function<int() const &> i;
+struct D {
+  template <typename Y, typename = is_function<Y>> D(Y);
+} b(&A::m_fn1<0>);
+

Reply via email to