re PR c++/48450 ([C++0x][SFINAE] Hard errors with static_cast expressions)
authorJason Merrill <jason@redhat.com>
Thu, 7 Apr 2011 21:47:45 +0000 (17:47 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Thu, 7 Apr 2011 21:47:45 +0000 (17:47 -0400)
PR c++/48450
* call.c (resolve_args): Take complain.
(build_new_function_call, build_operator_new_call): Pass it.
(build_op_call, build_new_op, build_new_method_call): Pass it.

From-SVN: r172146

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

index 26159e02d6af95887b890837bd05b835e1c09f89..976c7fb6f653b77669bca83c25af481cde663e6a 100644 (file)
@@ -1,5 +1,10 @@
 2011-04-07  Jason Merrill  <jason@redhat.com>
 
+       PR c++/48450
+       * call.c (resolve_args): Take complain.
+       (build_new_function_call, build_operator_new_call): Pass it.
+       (build_op_call, build_new_op, build_new_method_call): Pass it.
+
        PR c++/48450
        * typeck.c (check_for_casting_away_constness): Take complain.
        (build_static_cast_1, build_reinterpret_cast_1): Pass it.
index c2730271dcf2a87bf609e5cf007e88f3e1a977b3..f283bd116609fd76d7aa77eb9227c2964746d42d 100644 (file)
@@ -155,7 +155,6 @@ static tree convert_like_real (conversion *, tree, tree, int, int, bool,
                               bool, tsubst_flags_t);
 static void op_error (enum tree_code, enum tree_code, tree, tree,
                      tree, bool);
-static VEC(tree,gc) *resolve_args (VEC(tree,gc) *);
 static struct z_candidate *build_user_type_conversion_1 (tree, tree, int);
 static void print_z_candidate (const char *, struct z_candidate *);
 static void print_z_candidates (location_t, struct z_candidate *);
@@ -3525,7 +3524,7 @@ build_integral_nontype_arg_conv (tree type, tree expr, tsubst_flags_t complain)
 /* Do any initial processing on the arguments to a function call.  */
 
 static VEC(tree,gc) *
-resolve_args (VEC(tree,gc) *args)
+resolve_args (VEC(tree,gc) *args, tsubst_flags_t complain)
 {
   unsigned int ix;
   tree arg;
@@ -3536,7 +3535,8 @@ resolve_args (VEC(tree,gc) *args)
        return NULL;
       else if (VOID_TYPE_P (TREE_TYPE (arg)))
        {
-         error ("invalid use of void expression");
+         if (complain & tf_error)
+           error ("invalid use of void expression");
          return NULL;
        }
       else if (invalid_nonstatic_memfn_p (arg, tf_warning_or_error))
@@ -3636,7 +3636,7 @@ build_new_function_call (tree fn, VEC(tree,gc) **args, bool koenig_p,
 
   if (args != NULL && *args != NULL)
     {
-      *args = resolve_args (*args);
+      *args = resolve_args (*args, complain);
       if (*args == NULL)
        return error_mark_node;
     }
@@ -3707,7 +3707,7 @@ build_operator_new_call (tree fnname, VEC(tree,gc) **args,
   if (fn)
     *fn = NULL_TREE;
   VEC_safe_insert (tree, gc, *args, 0, *size);
-  *args = resolve_args (*args);
+  *args = resolve_args (*args, tf_warning_or_error);
   if (*args == NULL)
     return error_mark_node;
 
@@ -3820,7 +3820,7 @@ build_op_call (tree obj, VEC(tree,gc) **args, tsubst_flags_t complain)
 
   if (args != NULL && *args != NULL)
     {
-      *args = resolve_args (*args);
+      *args = resolve_args (*args, complain);
       if (*args == NULL)
        return error_mark_node;
     }
@@ -4864,7 +4864,7 @@ build_new_op (enum tree_code code, int flags, tree arg1, tree arg2, tree arg3,
          if (overloaded_p)
            *overloaded_p = true;
 
-         if (resolve_args (arglist) == NULL)
+         if (resolve_args (arglist, complain) == NULL)
            result = error_mark_node;
          else
            result = build_over_call (cand, LOOKUP_NORMAL, complain);
@@ -6850,7 +6850,7 @@ build_new_method_call (tree instance, tree fns, VEC(tree,gc) **args,
   /* Process the argument list.  */
   if (args != NULL && *args != NULL)
     {
-      *args = resolve_args (*args);
+      *args = resolve_args (*args, complain);
       if (*args == NULL)
        return error_mark_node;
     }
index 288bd1feb9d7c880af7d75805aedef5170a5e3ae..dcdd32d9895bb7d9bfecf5cdfc0ee1026ea589b8 100644 (file)
@@ -1,5 +1,7 @@
 2011-04-07  Jason Merrill  <jason@redhat.com>
 
+       * g++.dg/cpp0x/sfinae9.C: New.
+
        * c-c++-common/Wcast-qual-1.c: Move here from...
        * gcc.dg/cast-qual-3.c: ...here, and...
        * g++.dg/warn/Wcast-qual2.C: ...here.
diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae9.C b/gcc/testsuite/g++.dg/cpp0x/sfinae9.C
new file mode 100644 (file)
index 0000000..6f1de21
--- /dev/null
@@ -0,0 +1,24 @@
+// PR c++/48450
+// { dg-options -std=c++0x }
+
+namespace std {
+  template <class T> T&& declval();
+};
+
+template<class To, class From,
+  class = decltype(static_cast<To>(std::declval<From>()))
+>
+char f(int);
+
+template<class, class>
+char (&f(...))[2];
+
+struct A { virtual ~A() = 0; };
+struct B {};
+struct D : B {};
+
+static_assert(sizeof(f<A, int>(0)) != 1, "Error"); // a
+static_assert(sizeof(f<int*, const void*>(0)) != 1, "Error"); // b
+static_assert(sizeof(f<D*, const B*>(0)) != 1, "Error"); // c
+static_assert(sizeof(f<int B::*, const int D::*>(0)) != 1, "Error"); // d
+static_assert(sizeof(f<B, void>(0)) != 1, "Error"); // e