From patchwork Mon Oct 4 00:25:49 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: C++ PATCH for another sfinae case Date: Sun, 03 Oct 2010 14:25:49 -0000 From: Jason Merrill X-Patchwork-Id: 66608 Message-Id: <4CA91F0D.6020106@redhat.com> To: gcc-patches List Yet another case where we want to swallow an error during template deduction. Tested x86_64-pc-linux-gnu, applied to trunk. commit e8ae70530688aa2b0bcc0560773d55ff10d46017 Author: Jason Merrill Date: Sun Oct 3 14:27:03 2010 -0400 * typeck.c (require_complete_type_sfinae): Add complain parm to... (require_complete_type): ...this function. (cp_build_array_ref, convert_arguments): Use it. (convert_for_initialization, cp_build_modify_expr): Likewise. * cp-tree.h: Declare it. * call.c (build_over_call): Use it. diff --git a/gcc/cp/call.c b/gcc/cp/call.c index 2e7083d..e0911ac 100644 --- a/gcc/cp/call.c +++ b/gcc/cp/call.c @@ -5655,7 +5655,7 @@ build_over_call (struct z_candidate *cand, int flags, tsubst_flags_t complain) if (TREE_THIS_VOLATILE (fn) && cfun) current_function_returns_abnormally = 1; if (!VOID_TYPE_P (return_type)) - require_complete_type (return_type); + require_complete_type_sfinae (return_type, complain); return convert_from_reference (expr); } diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index aa1fe4d..6ce10e6 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5432,6 +5432,7 @@ extern int string_conv_p (const_tree, const_tree, int); extern tree cp_truthvalue_conversion (tree); extern tree condition_conversion (tree); extern tree require_complete_type (tree); +extern tree require_complete_type_sfinae (tree, tsubst_flags_t); extern tree complete_type (tree); extern tree complete_type_or_else (tree, tree); extern tree complete_type_or_maybe_complain (tree, tree, tsubst_flags_t); diff --git a/gcc/cp/typeck.c b/gcc/cp/typeck.c index eff6704..b2b8e5f 100644 --- a/gcc/cp/typeck.c +++ b/gcc/cp/typeck.c @@ -64,11 +64,11 @@ static int convert_arguments (tree, VEC(tree,gc) **, tree, int, /* Do `exp = require_complete_type (exp);' to make sure exp does not have an incomplete type. (That includes void types.) - Returns the error_mark_node if the VALUE does not have + Returns error_mark_node if the VALUE does not have complete type when this function returns. */ tree -require_complete_type (tree value) +require_complete_type_sfinae (tree value, tsubst_flags_t complain) { tree type; @@ -87,12 +87,18 @@ require_complete_type (tree value) if (COMPLETE_TYPE_P (type)) return value; - if (complete_type_or_else (type, value)) + if (complete_type_or_maybe_complain (type, value, complain)) return value; else return error_mark_node; } +tree +require_complete_type (tree value) +{ + return require_complete_type_sfinae (value, tf_warning_or_error); +} + /* Try to complete TYPE, if it is incomplete. For example, if TYPE is a template instantiation, do the instantiation. Returns TYPE, whether or not it could be completed, unless something goes @@ -3039,7 +3045,8 @@ cp_build_array_ref (location_t loc, tree array, tree idx, |= (CP_TYPE_VOLATILE_P (type) | TREE_SIDE_EFFECTS (array)); TREE_THIS_VOLATILE (rval) |= (CP_TYPE_VOLATILE_P (type) | TREE_THIS_VOLATILE (array)); - ret = require_complete_type (fold_if_not_in_template (rval)); + ret = require_complete_type_sfinae (fold_if_not_in_template (rval), + complain); protected_set_expr_location (ret, loc); return ret; } @@ -3542,7 +3549,7 @@ convert_arguments (tree typelist, VEC(tree,gc) **values, tree fndecl, /* Don't do ellipsis conversion for __built_in_constant_p as this will result in spurious errors for non-trivial types. */ - val = require_complete_type (val); + val = require_complete_type_sfinae (val, complain); else val = convert_arg_to_ellipsis (val); @@ -6744,7 +6751,7 @@ cp_build_modify_expr (tree lhs, enum tree_code modifycode, tree rhs, } else { - lhs = require_complete_type (lhs); + lhs = require_complete_type_sfinae (lhs, complain); if (lhs == error_mark_node) return error_mark_node; @@ -7592,7 +7599,7 @@ convert_for_initialization (tree exp, tree type, tree rhs, int flags, } if (exp != 0) - exp = require_complete_type (exp); + exp = require_complete_type_sfinae (exp, complain); if (exp == error_mark_node) return error_mark_node; diff --git a/gcc/testsuite/g++.dg/cpp0x/sfinae5.C b/gcc/testsuite/g++.dg/cpp0x/sfinae5.C new file mode 100644 index 0000000..8474fb3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/sfinae5.C @@ -0,0 +1,16 @@ +// { dg-options -std=c++0x } + +template +T&& create(); + +template () = create()) + > +char test(int); + +template +double test(...); + +int main() { + test(0); // #1 +}