re PR c++/54738 ([C++11][SFINAE] Hard errors for pointer-to-member function expressions)
authorPaolo Carlini <paolo.carlini@oracle.com>
Sat, 29 Sep 2012 22:58:31 +0000 (22:58 +0000)
committerPaolo Carlini <paolo@gcc.gnu.org>
Sat, 29 Sep 2012 22:58:31 +0000 (22:58 +0000)
/cp
2012-09-29  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/54738
* decl2.c (build_offset_ref_call_from_tree): Add tsubst_flags_t
parameter.
* pt.c (tsubst_copy_and_build): Adjust.
* parser.c (cp_parser_postfix_expression): Likewise.
* cp-tree.h: Adjust declaration.

/testsuite
2012-09-29  Paolo Carlini  <paolo.carlini@oracle.com>

PR c++/54738
* g++.dg/cpp0x/sfinae42.C: New.

From-SVN: r191862

gcc/cp/ChangeLog
gcc/cp/cp-tree.h
gcc/cp/decl2.c
gcc/cp/parser.c
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/sfinae42.C [new file with mode: 0644]

index 6550e16c654daa7698c3e4eee37e687f83da5b44..376cbf671fb44ba41e422ad4f1375a82fad4501c 100644 (file)
@@ -1,3 +1,12 @@
+2012-09-29  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/54738
+       * decl2.c (build_offset_ref_call_from_tree): Add tsubst_flags_t
+       parameter.
+       * pt.c (tsubst_copy_and_build): Adjust.
+       * parser.c (cp_parser_postfix_expression): Likewise.
+       * cp-tree.h: Adjust declaration.
+
 2012-09-28  Dodji Seketeli  <dodji@redhat.com>
 
        PR c++/54372 - unused attribute inactive on dependant entities
index ded247d93d1ff25ef8f823f5e1a397399ab3be0a..f4370224dd32b3f3c6a8e6cfeef342c1620dd8e9 100644 (file)
@@ -5149,7 +5149,8 @@ extern void determine_visibility          (tree);
 extern void constrain_class_visibility         (tree);
 extern void import_export_decl                 (tree);
 extern tree build_cleanup                      (tree);
-extern tree build_offset_ref_call_from_tree    (tree, VEC(tree,gc) **);
+extern tree build_offset_ref_call_from_tree    (tree, VEC(tree,gc) **,
+                                                tsubst_flags_t);
 extern bool decl_constant_var_p                        (tree);
 extern bool decl_maybe_constant_var_p          (tree);
 extern void check_default_args                 (tree);
index a590d1781561f1a5e29119ce73866576445547b1..4cff0516d776060e0fede79ea70f9104fbbbb9db 100644 (file)
@@ -4087,7 +4087,8 @@ cp_write_global_declarations (void)
    ARGS.  */
 
 tree
-build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args)
+build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args,
+                                tsubst_flags_t complain)
 {
   tree orig_fn;
   VEC(tree,gc) *orig_args = NULL;
@@ -4115,7 +4116,7 @@ build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args)
       if (TREE_CODE (TREE_TYPE (fn)) == METHOD_TYPE)
        {
          if (TREE_CODE (fn) == DOTSTAR_EXPR)
-           object = cp_build_addr_expr (object, tf_warning_or_error);
+           object = cp_build_addr_expr (object, complain);
          VEC_safe_insert (tree, gc, *args, 0, object);
        }
       /* Now that the arguments are done, transform FN.  */
@@ -4130,17 +4131,17 @@ build_offset_ref_call_from_tree (tree fn, VEC(tree,gc) **args)
        void B::g() { (this->*p)(); }  */
   if (TREE_CODE (fn) == OFFSET_REF)
     {
-      tree object_addr = cp_build_addr_expr (object, tf_warning_or_error);
+      tree object_addr = cp_build_addr_expr (object, complain);
       fn = TREE_OPERAND (fn, 1);
       fn = get_member_function_from_ptrfunc (&object_addr, fn,
-                                            tf_warning_or_error);
+                                            complain);
       VEC_safe_insert (tree, gc, *args, 0, object_addr);
     }
 
   if (CLASS_TYPE_P (TREE_TYPE (fn)))
-    expr = build_op_call (fn, args, tf_warning_or_error);
+    expr = build_op_call (fn, args, complain);
   else
-    expr = cp_build_function_call_vec (fn, args, tf_warning_or_error);
+    expr = cp_build_function_call_vec (fn, args, complain);
   if (processing_template_decl && expr != error_mark_node)
     expr = build_min_non_dep_call_vec (expr, orig_fn, orig_args);
 
index 40aa3061c0152eb21ca7006848bd1e8426d6af16..155b51a180d9f6168283aff464fd8d77733a4ee8 100644 (file)
@@ -5749,7 +5749,8 @@ cp_parser_postfix_expression (cp_parser *parser, bool address_p, bool cast_p,
                     || TREE_CODE (postfix_expression) == MEMBER_REF
                     || TREE_CODE (postfix_expression) == DOTSTAR_EXPR)
              postfix_expression = (build_offset_ref_call_from_tree
-                                   (postfix_expression, &args));
+                                   (postfix_expression, &args,
+                                    tf_warning_or_error));
            else if (idk == CP_ID_KIND_QUALIFIED)
              /* A call to a static class member, or a namespace-scope
                 function.  */
index d00470eec1831dd3b6207bee25b28fa91ff52e4b..104d4dd6898b32e0533d4075f32e26240c939d8f 100644 (file)
@@ -13783,7 +13783,8 @@ tsubst_copy_and_build (tree t,
          mark_used (function);
 
        if (TREE_CODE (function) == OFFSET_REF)
-         ret = build_offset_ref_call_from_tree (function, &call_args);
+         ret = build_offset_ref_call_from_tree (function, &call_args,
+                                                complain);
        else if (TREE_CODE (function) == COMPONENT_REF)
          {
            tree instance = TREE_OPERAND (function, 0);
index c7ef179b906290fa85b6a9ada431931bef31dce4..8578075ec2d64d070cf7fd16d49751d0fbbdb953 100644 (file)
@@ -1,3 +1,8 @@
+2012-09-29  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/54738
+       * g++.dg/cpp0x/sfinae42.C: New.
+
 2012-09-29  David Edelsohn  <dje.gcc@gmail.com>
 
        * gcc.target/powerpc/405-dlmzb-strlen-1.c: Skip on AIX.
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae42.C b/gcc/testsuite/g++.dg/cpp0x/sfinae42.C
new file mode 100644 (file)
index 0000000..a7a23a3
--- /dev/null
@@ -0,0 +1,46 @@
+// PR c++/54738
+// { dg-do compile { target c++11 } }
+
+template<class T>
+T&& declval();
+
+template<class F, class T1, class... Ts>
+decltype(((*declval<T1>()).*declval<F>())(declval<Ts>()...))
+test1(int);
+
+template<class...>
+void test1(...);
+
+template<class F, class T1, class... Ts>
+decltype((declval<T1>().*declval<F>())(declval<Ts>()...))
+test2(int);
+
+template<class...>
+void test2(...);
+
+struct S {};
+
+typedef void (S::*Func)(int) const;
+typedef void (S::*Func2)(int);
+
+typedef decltype(test1<Func, S*>(0)) type1a;
+typedef decltype(test1<Func, S*&>(0)) type1b;
+typedef decltype(test1<Func, S*, int, int>(0)) type1c;
+typedef decltype(test1<Func, S*&, int, int>(0)) type1d;
+
+typedef decltype(test2<Func, S>(0)) type2a;
+typedef decltype(test2<Func, S&>(0)) type2b;
+typedef decltype(test2<Func, S, int, int>(0)) type2c;
+typedef decltype(test2<Func, S&, int, int>(0)) type2d;
+
+typedef decltype(test1<Func, S*, S>(0)) type3a;
+typedef decltype(test1<Func, S*&, S>(0)) type3b;
+
+typedef decltype(test2<Func, S, S>(0)) type4a;
+typedef decltype(test2<Func, S&, S>(0)) type4b;
+
+typedef decltype(test1<Func2, const S*, int>(0)) type5a;
+typedef decltype(test1<Func2, const S*&, int>(0)) type5b;
+
+typedef decltype(test2<Func2, const S, int>(0)) type6a;
+typedef decltype(test2<Func2, const S&, int>(0)) type6b;