From: Paolo Carlini Date: Tue, 11 Sep 2012 01:05:12 +0000 (+0000) Subject: re PR c++/54541 (SFINAE bug: handling incomplete return types) X-Git-Tag: misc/gccgo-go1_1_2~947 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e2e030322038fa1b9bad7c567a09c8835dfd5183;p=thirdparty%2Fgcc.git re PR c++/54541 (SFINAE bug: handling incomplete return types) /cp 2012-09-10 Paolo Carlini 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. /testsuite 2012-09-10 Paolo Carlini PR c++/54541 PR c++/54542 * g++.dg/cpp0x/sfinae40.C: New. * g++.dg/cpp0x/sfinae41.C: Likewise. From-SVN: r191170 --- diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 72e6c512a645..bd620469df17 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,21 @@ +2012-09-10 Paolo Carlini + + 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 PR c++/54538 @@ -18,7 +36,7 @@ * decl.c (reshape_init_class): Avoid dereferencing a past-the-end pointer. - + 2012-09-07 Paolo Carlini * pt.c (num_template_headers_for_class): Rework per the code diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 159be6b7bca0..6f7e34669ce8 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -5525,7 +5525,7 @@ build_op_delete_call (enum tree_code code, tree addr, tree size, 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 { @@ -6127,12 +6127,12 @@ convert_arg_to_ellipsis (tree arg, tsubst_flags_t complain) 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)) { @@ -6882,7 +6882,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) 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. @@ -6890,7 +6890,8 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) 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; @@ -6923,12 +6924,12 @@ build_cxx_call (tree fn, int nargs, tree *argarray) 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); } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 3c55ba45b34c..ded247d93d1f 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -4918,7 +4918,8 @@ extern tree build_integral_nontype_arg_conv (tree, tree, tsubst_flags_t); 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 @@ -5851,7 +5852,8 @@ extern tree build_x_conditional_expr (location_t, tree, tree, tree, 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); diff --git a/gcc/cp/init.c b/gcc/cp/init.c index 23d86d5b1476..e5abec706cd0 100644 --- a/gcc/cp/init.c +++ b/gcc/cp/init.c @@ -2739,7 +2739,8 @@ build_new_1 (VEC(tree,gc) **placement, tree type, tree nelts, /* 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); } diff --git a/gcc/cp/optimize.c b/gcc/cp/optimize.c index 7011eb6f9f5d..ec2833555213 100644 --- a/gcc/cp/optimize.c +++ b/gcc/cp/optimize.c @@ -128,7 +128,8 @@ build_delete_destructor_body (tree delete_dtor, tree complete_dtor) /* 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)); diff --git a/gcc/cp/rtti.c b/gcc/cp/rtti.c index e61918094a5b..95518cffe1d0 100644 --- a/gcc/cp/rtti.c +++ b/gcc/cp/rtti.c @@ -206,7 +206,7 @@ throw_bad_cast (void) 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 @@ -225,7 +225,7 @@ throw_bad_typeid (void) 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); } /* Return an lvalue expression whose type is "const std::type_info" @@ -743,7 +743,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst_flags_t complain) 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) { diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index f62532153fd1..97a4588157e6 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -3373,7 +3373,7 @@ cp_build_function_call_vec (tree function, VEC(tree,gc) **params, 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); @@ -5719,7 +5719,8 @@ build_x_compound_expr_from_list (tree list, expr_list_kind exp, /* 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; @@ -5732,14 +5733,19 @@ build_x_compound_expr_from_vec (VEC(tree,gc) *vec, const char *msg) 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; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index bd147805cbc8..bc9c0afac9aa 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2012-09-10 Paolo Carlini + + PR c++/54541 + PR c++/54542 + * g++.dg/cpp0x/sfinae40.C: New. + * g++.dg/cpp0x/sfinae41.C: Likewise. + 2012-09-10 Jason Merrill PR c++/54538 diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae40.C b/gcc/testsuite/g++.dg/cpp0x/sfinae40.C new file mode 100644 index 000000000000..18e5fecb2681 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae40.C @@ -0,0 +1,21 @@ +// PR c++/54541 +// { dg-do compile { target c++11 } } + +template T&& declval(); + +struct X; + +X f(int); + +template +void g(decltype((void)f(declval())) *) +{} + +template +void g(...) +{} + +int main() +{ + g(0); +} diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae41.C b/gcc/testsuite/g++.dg/cpp0x/sfinae41.C new file mode 100644 index 000000000000..bd6f624f0adc --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae41.C @@ -0,0 +1,17 @@ +// PR c++/54542 +// { dg-do compile { target c++11 } } + +template +void f(decltype(new T(1, 2)) *) +{ + T(1, 2); +} + +template +void f(...) +{} + +int main() +{ + f(0); +}