The issue here was that can_convert_bad doesn't allow this ill-formed
conversion, but instantiate_type does (with -fpermissive).  Fixed by
recognizing that case.  It might be nice to make can_convert_bad
smarter, but that doesn't seem worth the effort.

Tested x86_64-pc-linux-gnu, applying to trunk.
commit 8c545e7c3e1babf7a97e22f061953c4fa5c7871a
Author: Jason Merrill <ja...@redhat.com>
Date:   Wed Mar 15 17:08:42 2017 -0400

            PR c++/80043 - ICE with -fpermissive
    
            * typeck.c (convert_for_assignment): Handle instantiate_type
            not giving an error.

diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c
index d111124..4e9a1c0 100644
--- a/gcc/cp/typeck.c
+++ b/gcc/cp/typeck.c
@@ -8486,7 +8486,12 @@ convert_for_assignment (tree type, tree rhs,
                 overloaded function.  Call instantiate_type to get error
                 messages.  */
              if (rhstype == unknown_type_node)
-               instantiate_type (type, rhs, tf_warning_or_error);
+               {
+                 tree r = instantiate_type (type, rhs, tf_warning_or_error);
+                 /* -fpermissive might allow this.  */
+                 if (!seen_error ())
+                   return r;
+               }
              else if (fndecl)
                error ("cannot convert %qT to %qT for argument %qP to %qD",
                       rhstype, type, parmnum, fndecl);
diff --git a/gcc/testsuite/g++.dg/parse/ptrmem7.C 
b/gcc/testsuite/g++.dg/parse/ptrmem7.C
new file mode 100644
index 0000000..37b2689
--- /dev/null
+++ b/gcc/testsuite/g++.dg/parse/ptrmem7.C
@@ -0,0 +1,16 @@
+// PR c++/80043
+// { dg-options -fpermissive }
+
+struct A
+{
+  template<int> void foo()
+  {
+    void (A::* fp)();
+    fp = A::foo<0>;            // { dg-warning "assuming pointer to member" }
+  }
+};
+
+void bar()
+{
+  A().foo<0>();
+}

Reply via email to