PR c++/71568 - SFINAE forming pointer to member function
authorJason Merrill <jason@redhat.com>
Mon, 27 Feb 2017 20:17:17 +0000 (15:17 -0500)
committerJason Merrill <jason@gcc.gnu.org>
Mon, 27 Feb 2017 20:17:17 +0000 (15:17 -0500)
* init.c (build_offset_ref): Check the return value of
perform_or_defer_access_check.

From-SVN: r245763

gcc/cp/ChangeLog
gcc/cp/init.c
gcc/testsuite/g++.dg/cpp0x/sfinae58.C [new file with mode: 0644]

index 03f92565772c1391f13dd11080be5d0906846235..5792e5d08d0068b06f25929d3e9c114174e48671 100644 (file)
@@ -1,3 +1,9 @@
+2017-02-27  Jason Merrill  <jason@redhat.com>
+
+       PR c++/71568 - SFINAE forming pointer to member function
+       * init.c (build_offset_ref): Check the return value of
+       perform_or_defer_access_check.
+
 2017-02-27  Marek Polacek  <polacek@redhat.com>
 
        * decl.c (expand_static_init): Add missing } in a comment.
index b8308227988aea10c738706cb24b8bc5cbaa30b5..99eeb8a893f0442592b12c831de4d6171e017b2d 100644 (file)
@@ -2043,14 +2043,16 @@ build_offset_ref (tree type, tree member, bool address_p,
               If the access is to form a pointer to member, the
               nested-name-specifier shall name the derived class
               (or any class derived from that class).  */
+         bool ok;
          if (address_p && DECL_P (t)
              && DECL_NONSTATIC_MEMBER_P (t))
-           perform_or_defer_access_check (TYPE_BINFO (type), t, t,
-                                          complain);
+           ok = perform_or_defer_access_check (TYPE_BINFO (type), t, t,
+                                               complain);
          else
-           perform_or_defer_access_check (basebinfo, t, t,
-                                          complain);
-
+           ok = perform_or_defer_access_check (basebinfo, t, t,
+                                               complain);
+         if (!ok)
+           return error_mark_node;
          if (DECL_STATIC_FUNCTION_P (t))
            return t;
          member = t;
@@ -2059,11 +2061,14 @@ build_offset_ref (tree type, tree member, bool address_p,
        TREE_TYPE (member) = unknown_type_node;
     }
   else if (address_p && TREE_CODE (member) == FIELD_DECL)
-    /* We need additional test besides the one in
-       check_accessibility_of_qualified_id in case it is
-       a pointer to non-static member.  */
-    perform_or_defer_access_check (TYPE_BINFO (type), member, member,
-                                  complain);
+    {
+      /* We need additional test besides the one in
+        check_accessibility_of_qualified_id in case it is
+        a pointer to non-static member.  */
+      if (!perform_or_defer_access_check (TYPE_BINFO (type), member, member,
+                                         complain))
+       return error_mark_node;
+    }
 
   if (!address_p)
     {
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae58.C b/gcc/testsuite/g++.dg/cpp0x/sfinae58.C
new file mode 100644 (file)
index 0000000..aaa38d3
--- /dev/null
@@ -0,0 +1,12 @@
+// PR c++/71568
+// { dg-do compile { target c++11 } }
+
+template <typename T> class F : T {};
+template <typename> using void_t = void;
+template <class, class = void> struct G;
+template <typename T> struct G<T, void_t<decltype(&T::nlog_custom)>> {};
+struct D {
+  void nlog_custom();
+};
+G<F<D>> g;                     // { dg-error "incomplete" }
+