From patchwork Mon Oct 4 00:25:49 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Merrill X-Patchwork-Id: 66608 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id CE6F9B70AE for ; Mon, 4 Oct 2010 11:26:01 +1100 (EST) Received: (qmail 7590 invoked by alias); 4 Oct 2010 00:25:59 -0000 Received: (qmail 7518 invoked by uid 22791); 4 Oct 2010 00:25:58 -0000 X-SWARE-Spam-Status: No, hits=-6.1 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_HI, SPF_HELO_PASS, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Mon, 04 Oct 2010 00:25:53 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o940Pp7H018227 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Sun, 3 Oct 2010 20:25:51 -0400 Received: from [127.0.0.1] (ovpn-113-72.phx2.redhat.com [10.3.113.72]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o940PocK002595 for ; Sun, 3 Oct 2010 20:25:50 -0400 Message-ID: <4CA91F0D.6020106@redhat.com> Date: Sun, 03 Oct 2010 20:25:49 -0400 From: Jason Merrill User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.1.14) Gecko/20101002 Lightning/1.0b1 Shredder/3.0.9pre MIME-Version: 1.0 To: gcc-patches List Subject: C++ PATCH for another sfinae case Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 +}