+2012-09-10  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/54541
+       PR c++/54542
+       * call.c (build_cxx_call): Add tsubst_flags_t parameter, use
+       require_complete_type_sfinae.
+       (build_op_delete_call, build_over_call): Adjust.
+       * typeck.c (build_x_compound_expr_from_vec): Add tsubst_flags_t
+       parameter.
+       (cp_build_function_call_vec): Adjust.
+       * init.c (build_new_1): Likewise.
+       * rtti.c (throw_bad_cast, throw_bad_typeid, build_dynamic_cast_1):
+       Likewise.
+       * optimize.c (build_delete_destructor_body): Likewise.
+       * cp-tree.h: Adjust declarations.
+
+       * call.c (convert_arg_to_ellipsis): Use require_complete_type_sfinae.
+
 2012-09-10  Jason Merrill  <jason@redhat.com>
 
        PR c++/54538
 
        * decl.c (reshape_init_class): Avoid dereferencing a
        past-the-end pointer.
-                 
+
 2012-09-07  Paolo Carlini  <paolo.carlini@oracle.com>
 
        * pt.c (num_template_headers_for_class): Rework per the code
 
          for (i = 1; i < nargs; i++)
            argarray[i] = CALL_EXPR_ARG (placement, i);
          mark_used (fn);
-         return build_cxx_call (fn, nargs, argarray);
+         return build_cxx_call (fn, nargs, argarray, complain);
        }
       else
        {
       arg = cp_perform_integral_promotions (arg, complain);
     }
 
-  arg = require_complete_type (arg);
+  arg = require_complete_type_sfinae (arg, complain);
   arg_type = TREE_TYPE (arg);
 
   if (arg != error_mark_node
       /* In a template (or ill-formed code), we can have an incomplete type
-        even after require_complete_type, in which case we don't know
+        even after require_complete_type_sfinae, in which case we don't know
         whether it has trivial copy or not.  */
       && COMPLETE_TYPE_P (arg_type))
     {
        return error_mark_node;
     }
 
-  return build_cxx_call (fn, nargs, argarray);
+  return build_cxx_call (fn, nargs, argarray, complain);
 }
 
 /* Build and return a call to FN, using NARGS arguments in ARGARRAY.
    high-level operations.  */
 
 tree
-build_cxx_call (tree fn, int nargs, tree *argarray)
+build_cxx_call (tree fn, int nargs, tree *argarray,
+               tsubst_flags_t complain)
 {
   tree fndecl;
   int optimize_sav;
   if (VOID_TYPE_P (TREE_TYPE (fn)))
     return fn;
 
-  fn = require_complete_type (fn);
+  fn = require_complete_type_sfinae (fn, complain);
   if (fn == error_mark_node)
     return error_mark_node;
 
   if (MAYBE_CLASS_TYPE_P (TREE_TYPE (fn)))
-    fn = build_cplus_new (TREE_TYPE (fn), fn, tf_warning_or_error);
+    fn = build_cplus_new (TREE_TYPE (fn), fn, complain);
   return convert_from_reference (fn);
 }
 
 
 extern tree perform_direct_initialization_if_possible (tree, tree, bool,
                                                        tsubst_flags_t);
 extern tree in_charge_arg_for_name             (tree);
-extern tree build_cxx_call                     (tree, int, tree *);
+extern tree build_cxx_call                     (tree, int, tree *,
+                                                tsubst_flags_t);
 extern bool is_std_init_list                   (tree);
 extern bool is_list_ctor                       (tree);
 #ifdef ENABLE_CHECKING
                                                  tsubst_flags_t);
 extern tree build_x_compound_expr_from_list    (tree, expr_list_kind,
                                                 tsubst_flags_t);
-extern tree build_x_compound_expr_from_vec     (VEC(tree,gc) *, const char *);
+extern tree build_x_compound_expr_from_vec     (VEC(tree,gc) *, const char *,
+                                                tsubst_flags_t);
 extern tree build_x_compound_expr              (location_t, tree, tree,
                                                 tsubst_flags_t);
 extern tree build_compound_expr                 (location_t, tree, tree);
 
              /* We are processing something like `new int (10)', which
                 means allocate an int, and initialize it with 10.  */
 
-             ie = build_x_compound_expr_from_vec (*init, "new initializer");
+             ie = build_x_compound_expr_from_vec (*init, "new initializer",
+                                                  complain);
              init_expr = cp_build_modify_expr (init_expr, INIT_EXPR, ie,
                                                complain);
            }
 
 
   /* Call the corresponding complete destructor.  */
   gcc_assert (complete_dtor);
-  call_dtor = build_cxx_call (complete_dtor, 1, &parm);
+  call_dtor = build_cxx_call (complete_dtor, 1, &parm,
+                             tf_warning_or_error);
   add_stmt (call_dtor);
 
   add_stmt (build_stmt (0, LABEL_EXPR, cdtor_label));
 
     fn = push_throw_library_fn (fn, build_function_type_list (ptr_type_node,
                                                              NULL_TREE));
 
-  return build_cxx_call (fn, 0, NULL);
+  return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
 }
 
 /* Return an expression for "__cxa_bad_typeid()".  The expression
       fn = push_throw_library_fn (fn, t);
     }
 
-  return build_cxx_call (fn, 0, NULL);
+  return build_cxx_call (fn, 0, NULL, tf_warning_or_error);
 }
 \f
 /* Return an lvalue expression whose type is "const std::type_info"
              pop_abi_namespace ();
              dynamic_cast_node = dcast_fn;
            }
-         result = build_cxx_call (dcast_fn, 4, elems);
+         result = build_cxx_call (dcast_fn, 4, elems, complain);
 
          if (tc == REFERENCE_TYPE)
            {
 
      null parameters.  */
   check_function_arguments (fntype, nargs, argarray);
 
-  ret = build_cxx_call (function, nargs, argarray);
+  ret = build_cxx_call (function, nargs, argarray, complain);
 
   if (allocated != NULL)
     release_tree_vector (allocated);
 /* Like build_x_compound_expr_from_list, but using a VEC.  */
 
 tree
-build_x_compound_expr_from_vec (VEC(tree,gc) *vec, const char *msg)
+build_x_compound_expr_from_vec (VEC(tree,gc) *vec, const char *msg,
+                               tsubst_flags_t complain)
 {
   if (VEC_empty (tree, vec))
     return NULL_TREE;
       tree t;
 
       if (msg != NULL)
-       permerror (input_location,
-                  "%s expression list treated as compound expression",
-                  msg);
+       {
+         if (complain & tf_error)
+           permerror (input_location,
+                      "%s expression list treated as compound expression",
+                      msg);
+         else
+           return error_mark_node;
+       }
 
       expr = VEC_index (tree, vec, 0);
       for (ix = 1; VEC_iterate (tree, vec, ix, t); ++ix)
        expr = build_x_compound_expr (EXPR_LOCATION (t), expr,
-                                     t, tf_warning_or_error);
+                                     t, complain);
 
       return expr;
     }
 
+2012-09-10  Paolo Carlini  <paolo.carlini@oracle.com>
+
+       PR c++/54541
+       PR c++/54542
+       * g++.dg/cpp0x/sfinae40.C: New.
+       * g++.dg/cpp0x/sfinae41.C: Likewise.
+
 2012-09-10  Jason Merrill  <jason@redhat.com>
 
        PR c++/54538
 
--- /dev/null
+// PR c++/54541
+// { dg-do compile { target c++11 } }
+
+template <typename T> T&& declval();
+
+struct X;
+
+X f(int);
+
+template <class T>
+void g(decltype((void)f(declval<T>())) *)
+{}
+
+template <class T>
+void g(...)
+{}
+
+int main()
+{
+  g<int>(0);
+}
 
--- /dev/null
+// PR c++/54542
+// { dg-do compile { target c++11 } }
+
+template <class T>
+void f(decltype(new T(1, 2)) *)
+{
+  T(1, 2);
+}
+
+template <class T>
+void f(...)
+{}
+
+int main()
+{
+  f<int>(0);
+}