]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
re PR c++/44967 ([C++0x] decltype of method call dependent on pack expansion crashes)
authorJason Merrill <jason@redhat.com>
Tue, 20 Jul 2010 17:34:18 +0000 (13:34 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 20 Jul 2010 17:34:18 +0000 (13:34 -0400)
PR c++/44967
* pt.c (tsubst_copy_and_build): Handle partial substitution of
CALL_EXPR.

From-SVN: r162343

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

index 124fbe2f191ac01c77a06c05c8e79615083d8c86..b2b0279baf56fa6359151419d211293ec652ddf0 100644 (file)
@@ -1,3 +1,9 @@
+2010-07-20  Jason Merrill  <jason@redhat.com>
+
+       PR c++/44967
+       * pt.c (tsubst_copy_and_build): Handle partial substitution of
+       CALL_EXPR.
+
 2010-07-19  Jason Merrill  <jason@redhat.com>
 
        PR c++/44996
index 0ccd8d9df5d5e7dd113126045aba4df5788177dc..a992d6f5f7c5aa245fee2212902811d775d47453 100644 (file)
@@ -12500,6 +12500,15 @@ tsubst_copy_and_build (tree t,
              }
          }
 
+       if (processing_template_decl
+           && (type_dependent_expression_p (function)
+               || any_type_dependent_arguments_p (call_args)))
+         {
+           ret = build_nt_call_vec (function, call_args);
+           KOENIG_LOOKUP_P (ret) = koenig_p;
+           goto call_out;
+         }
+
        /* We do not perform argument-dependent lookup if normal
           lookup finds a non-function, in accordance with the
           expected resolution of DR 218.  */
@@ -12512,15 +12521,14 @@ tsubst_copy_and_build (tree t,
                || TREE_CODE (function) == IDENTIFIER_NODE)
            /* Only do this when substitution turns a dependent call
               into a non-dependent call.  */
-           && type_dependent_expression_p_push (t)
-           && !any_type_dependent_arguments_p (call_args))
+           && type_dependent_expression_p_push (t))
          function = perform_koenig_lookup (function, call_args);
 
        if (TREE_CODE (function) == IDENTIFIER_NODE)
          {
            unqualified_name_lookup_error (function);
-           release_tree_vector (call_args);
-           return error_mark_node;
+           ret = error_mark_node;
+           goto call_out;
          }
 
        /* Remember that there was a reference to this entity.  */
@@ -12551,6 +12559,7 @@ tsubst_copy_and_build (tree t,
                                  koenig_p,
                                  complain);
 
+      call_out:
        release_tree_vector (call_args);
 
        return ret;
index 402d31dc61a5b40888cece1b357ab37fdf40ee02..902c9cd1f4b0f17764d84e90bd58fa547dd09fe8 100644 (file)
@@ -1,3 +1,8 @@
+2010-07-20  Jason Merrill  <jason@redhat.com>
+
+       PR c++/44967
+       * g++.dg/cpp0x/sfinae2.C: New.
+
 2010-07-20  Richard Guenther  <rguenther@suse.de>
 
        PR lto/42696
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae2.C b/gcc/testsuite/g++.dg/cpp0x/sfinae2.C
new file mode 100644 (file)
index 0000000..b9ef70d
--- /dev/null
@@ -0,0 +1,39 @@
+// PR c++/44967
+// { dg-options -std=c++0x }
+
+template <typename T> T&& declval();
+
+template<typename T1, typename T2, typename... Args>
+struct has_construct
+{
+    typedef char one;
+    typedef struct {char _m[2]; } two;
+
+    template<typename U1, typename U2, typename... Args2>
+    static decltype(declval<U1>().construct(declval<U2*>(), declval<Args2>()...), one()) test(int);
+    template<typename, typename, typename...>
+    static two test(...);
+
+    static const bool value = sizeof(test<T1, T2, Args...>(0)) == 1;
+};
+
+
+struct A0
+{};
+
+struct A1
+{
+    void construct(int*, int);
+};
+
+template<typename _Tp>
+struct A2
+{
+  template<typename _Tp1, typename... _Args>
+  void construct(_Tp1*, _Args&&...) {}
+};
+
+#define SA(X) static_assert(X,#X)
+SA((!has_construct<A0, int, int>::value)); // ok
+SA((has_construct<A1, int, int>::value)); // bang
+SA((has_construct<A2<int>, int>::value)); // bang