From patchwork Fri Sep 23 23:45:37 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Carlini X-Patchwork-Id: 116201 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 C770AB6F80 for ; Sat, 24 Sep 2011 09:46:57 +1000 (EST) Received: (qmail 6357 invoked by alias); 23 Sep 2011 23:46:56 -0000 Received: (qmail 6344 invoked by uid 22791); 23 Sep 2011 23:46:54 -0000 X-SWARE-Spam-Status: No, hits=-2.3 required=5.0 tests=AWL, BAYES_00, RP_MATCHES_RCVD, TW_VF X-Spam-Check-By: sourceware.org Received: from acsinet15.oracle.com (HELO acsinet15.oracle.com) (141.146.126.227) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 23 Sep 2011 23:46:39 +0000 Received: from acsinet21.oracle.com (acsinet21.oracle.com [141.146.126.237]) by acsinet15.oracle.com (Switch-3.4.4/Switch-3.4.4) with ESMTP id p8NNkauT022843 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Fri, 23 Sep 2011 23:46:37 GMT Received: from acsmt358.oracle.com (acsmt358.oracle.com [141.146.40.158]) by acsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id p8NNkZmo027361 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Fri, 23 Sep 2011 23:46:35 GMT Received: from abhmt116.oracle.com (abhmt116.oracle.com [141.146.116.68]) by acsmt358.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id p8NNkUA6030704; Fri, 23 Sep 2011 18:46:30 -0500 Received: from [192.168.1.4] (/79.47.193.38) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Fri, 23 Sep 2011 16:46:29 -0700 Message-ID: <4E7D1A21.5010903@oracle.com> Date: Sat, 24 Sep 2011 01:45:37 +0200 From: Paolo Carlini User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:6.0.2) Gecko/20110907 Thunderbird/6.0.2 MIME-Version: 1.0 To: "gcc-patches@gcc.gnu.org" CC: Jason Merrill Subject: [C++ Patch] PR 44267 X-IsSubscribed: yes 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 Hi, as agreed on the audit trail. Tested x86_64-linux. Ok for mainline? Thanks, Paolo. //////////////////////// /cp 2011-09-23 Paolo Carlini PR c++/44267 * class.c (build_base_path): Add a tsubst_flags_t parameter. (convert_to_base): Adjust call. * typeck.c (build_class_member_access_expr, get_member_function_from_ptrfunc, build_static_cast_1): Likewise. * init.c (dfs_initialize_vtbl_ptrs, emit_mem_initializers): Likewise. * method.c (do_build_copy_constructor, do_build_copy_assign): Likewise. * rtti.c (build_dynamic_cast_1): Likewise. * typeck2.c (build_scoped_ref, build_m_component_ref): Likewise. * call.c (build_over_call, build_special_member_call): Likewise. * cvt.c (cp_convert_to_pointer, convert_to_pointer_force, build_up_reference): Likewise. * cp-tree.h (build_base_path): Adjust declaration. /testsuite 2011-09-23 Paolo Carlini PR c++/44267 * g++.dg/template/sfinae28.C: New. Index: testsuite/g++.dg/template/sfinae28.C =================================================================== --- testsuite/g++.dg/template/sfinae28.C (revision 0) +++ testsuite/g++.dg/template/sfinae28.C (revision 0) @@ -0,0 +1,24 @@ +// Origin: PR c++/44267 + +struct B {}; +struct D : B {}; +struct VD : virtual B {}; + +template T create(); + +typedef char one[1]; +typedef char two[2]; + +template +one& f(char (*)[sizeof(static_cast(create()))]); + +template +two& f(...); + +int main() +{ + f(0); + f(0); + f(0); + return 0; +} Index: cp/typeck.c =================================================================== --- cp/typeck.c (revision 179128) +++ cp/typeck.c (working copy) @@ -2221,7 +2221,7 @@ build_class_member_access_expr (tree object, tree /* Convert to the base. */ object = build_base_path (PLUS_EXPR, object, binfo, - /*nonnull=*/1); + /*nonnull=*/1, complain); /* If we found the base successfully then we should be able to convert to it successfully. */ gcc_assert (object != error_mark_node); @@ -3073,7 +3073,7 @@ get_member_function_from_ptrfunc (tree *instance_p basetype = lookup_base (TREE_TYPE (TREE_TYPE (instance_ptr)), basetype, ba_check, NULL); instance_ptr = build_base_path (PLUS_EXPR, instance_ptr, basetype, - 1); + 1, tf_warning_or_error); if (instance_ptr == error_mark_node) return error_mark_node; } @@ -5772,7 +5772,7 @@ build_static_cast_1 (tree type, tree expr, bool c_ /* Convert from "B*" to "D*". This function will check that "B" is not a virtual base of "D". */ expr = build_base_path (MINUS_EXPR, build_address (expr), - base, /*nonnull=*/false); + base, /*nonnull=*/false, complain); /* Convert the pointer to a reference -- but then remember that there are no expressions with reference type in C++. @@ -5874,7 +5874,8 @@ build_static_cast_1 (tree type, tree expr, bool c_ base = lookup_base (TREE_TYPE (type), TREE_TYPE (intype), c_cast_p ? ba_unique : ba_check, NULL); - expr = build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false); + expr = build_base_path (MINUS_EXPR, expr, base, /*nonnull=*/false, + complain); return cp_fold_convert(type, expr); } Index: cp/init.c =================================================================== --- cp/init.c (revision 179128) +++ cp/init.c (working copy) @@ -100,7 +100,8 @@ dfs_initialize_vtbl_ptrs (tree binfo, void *data) { tree base_ptr = TREE_VALUE ((tree) data); - base_ptr = build_base_path (PLUS_EXPR, base_ptr, binfo, /*nonnull=*/1); + base_ptr = build_base_path (PLUS_EXPR, base_ptr, binfo, /*nonnull=*/1, + tf_warning_or_error); expand_virtual_init (binfo, base_ptr); } @@ -963,7 +964,7 @@ emit_mem_initializers (tree mem_inits) tree base_addr; base_addr = build_base_path (PLUS_EXPR, current_class_ptr, - subobject, 1); + subobject, 1, tf_warning_or_error); expand_aggr_init_1 (subobject, NULL_TREE, cp_build_indirect_ref (base_addr, RO_NULL, tf_warning_or_error), Index: cp/class.c =================================================================== --- cp/class.c (revision 179128) +++ cp/class.c (working copy) @@ -235,7 +235,8 @@ tree build_base_path (enum tree_code code, tree expr, tree binfo, - int nonnull) + int nonnull, + tsubst_flags_t complain) { tree v_binfo = NULL_TREE; tree d_binfo = NULL_TREE; @@ -276,14 +277,16 @@ build_base_path (enum tree_code code, if (code == MINUS_EXPR && v_binfo) { - error ("cannot convert from base %qT to derived type %qT via virtual base %qT", - BINFO_TYPE (binfo), BINFO_TYPE (d_binfo), BINFO_TYPE (v_binfo)); + if (complain & tf_error) + error ("cannot convert from base %qT to derived type %qT via " + "virtual base %qT", BINFO_TYPE (binfo), BINFO_TYPE (d_binfo), + BINFO_TYPE (v_binfo)); return error_mark_node; } if (!want_pointer) /* This must happen before the call to save_expr. */ - expr = cp_build_addr_expr (expr, tf_warning_or_error); + expr = cp_build_addr_expr (expr, complain); else expr = mark_rvalue_use (expr); @@ -341,7 +344,7 @@ build_base_path (enum tree_code code, interesting to the optimizers anyway. */ && !has_empty) { - expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error); + expr = cp_build_indirect_ref (expr, RO_NULL, complain); expr = build_simple_base_path (expr, binfo); if (want_pointer) expr = build_address (expr); @@ -366,19 +369,18 @@ build_base_path (enum tree_code code, t = TREE_TYPE (TYPE_VFIELD (current_class_type)); t = build_pointer_type (t); v_offset = convert (t, current_vtt_parm); - v_offset = cp_build_indirect_ref (v_offset, RO_NULL, - tf_warning_or_error); + v_offset = cp_build_indirect_ref (v_offset, RO_NULL, complain); } else v_offset = build_vfield_ref (cp_build_indirect_ref (expr, RO_NULL, - tf_warning_or_error), + complain), TREE_TYPE (TREE_TYPE (expr))); v_offset = fold_build_pointer_plus (v_offset, BINFO_VPTR_FIELD (v_binfo)); v_offset = build1 (NOP_EXPR, build_pointer_type (ptrdiff_type_node), v_offset); - v_offset = cp_build_indirect_ref (v_offset, RO_NULL, tf_warning_or_error); + v_offset = cp_build_indirect_ref (v_offset, RO_NULL, complain); TREE_CONSTANT (v_offset) = 1; offset = convert_to_integer (ptrdiff_type_node, @@ -418,7 +420,7 @@ build_base_path (enum tree_code code, null_test = NULL; if (!want_pointer) - expr = cp_build_indirect_ref (expr, RO_NULL, tf_warning_or_error); + expr = cp_build_indirect_ref (expr, RO_NULL, complain); out: if (null_test) @@ -523,7 +525,7 @@ convert_to_base (tree object, tree type, bool chec if (!binfo || binfo == error_mark_node) return error_mark_node; - return build_base_path (PLUS_EXPR, object, binfo, nonnull); + return build_base_path (PLUS_EXPR, object, binfo, nonnull, complain); } /* EXPR is an expression with unqualified class type. BASE is a base Index: cp/method.c =================================================================== --- cp/method.c (revision 179128) +++ cp/method.c (working copy) @@ -516,7 +516,8 @@ do_build_copy_constructor (tree fndecl) for (vbases = CLASSTYPE_VBASECLASSES (current_class_type), i = 0; VEC_iterate (tree, vbases, i, binfo); i++) { - init = build_base_path (PLUS_EXPR, parm, binfo, 1); + init = build_base_path (PLUS_EXPR, parm, binfo, 1, + tf_warning_or_error); if (move_p) init = move (init); member_init_list @@ -531,7 +532,8 @@ do_build_copy_constructor (tree fndecl) if (BINFO_VIRTUAL_P (base_binfo)) continue; - init = build_base_path (PLUS_EXPR, parm, base_binfo, 1); + init = build_base_path (PLUS_EXPR, parm, base_binfo, 1, + tf_warning_or_error); if (move_p) init = move (init); member_init_list @@ -624,7 +626,8 @@ do_build_copy_assign (tree fndecl) /* We must convert PARM directly to the base class explicitly since the base class may be ambiguous. */ - converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1); + converted_parm = build_base_path (PLUS_EXPR, parm, base_binfo, 1, + tf_warning_or_error); if (move_p) converted_parm = move (converted_parm); /* Call the base class assignment operator. */ Index: cp/rtti.c =================================================================== --- cp/rtti.c (revision 179128) +++ cp/rtti.c (working copy) @@ -1,6 +1,6 @@ /* RunTime Type Identification Copyright (C) 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2008, 2009, 2010 + 2005, 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc. Mostly written by Jason Merrill (jason@cygnus.com). @@ -616,7 +616,7 @@ build_dynamic_cast_1 (tree type, tree expr, tsubst if (binfo) { expr = build_base_path (PLUS_EXPR, convert_from_reference (expr), - binfo, 0); + binfo, 0, complain); if (TREE_CODE (exprtype) == POINTER_TYPE) expr = rvalue (expr); return expr; Index: cp/typeck2.c =================================================================== --- cp/typeck2.c (revision 179128) +++ cp/typeck2.c (working copy) @@ -1398,7 +1398,8 @@ build_scoped_ref (tree datum, tree basetype, tree* } *binfo_p = binfo; - return build_base_path (PLUS_EXPR, datum, binfo, 1); + return build_base_path (PLUS_EXPR, datum, binfo, 1, + tf_warning_or_error); } /* Build a reference to an object specified by the C++ `->' operator. @@ -1565,7 +1566,8 @@ build_m_component_ref (tree datum, tree component) /* Convert object to the correct base. */ if (binfo) - datum = build_base_path (PLUS_EXPR, datum, binfo, 1); + datum = build_base_path (PLUS_EXPR, datum, binfo, 1, + tf_warning_or_error); /* Build an expression for "object + offset" where offset is the value stored in the pointer-to-data-member. */ Index: cp/call.c =================================================================== --- cp/call.c (revision 179128) +++ cp/call.c (working copy) @@ -6449,7 +6449,7 @@ build_over_call (struct z_candidate *cand, int fla converted_arg = build_base_path (PLUS_EXPR, arg, cand->conversion_path, - 1); + 1, complain); /* Check that the base class is accessible. */ if (!accessible_base_p (TREE_TYPE (argtype), BINFO_TYPE (cand->conversion_path), true)) @@ -6462,7 +6462,7 @@ build_over_call (struct z_candidate *cand, int fla base_binfo = lookup_base (TREE_TYPE (TREE_TYPE (converted_arg)), TREE_TYPE (parmtype), ba_unique, NULL); converted_arg = build_base_path (PLUS_EXPR, converted_arg, - base_binfo, 1); + base_binfo, 1, complain); argarray[j++] = converted_arg; parm = TREE_CHAIN (parm); @@ -6706,7 +6706,8 @@ build_over_call (struct z_candidate *cand, int fla if (TREE_DEPRECATED (fn)) warn_deprecated_use (fn, NULL_TREE); - argarray[0] = build_base_path (PLUS_EXPR, argarray[0], binfo, 1); + argarray[0] = build_base_path (PLUS_EXPR, argarray[0], binfo, 1, + complain); if (TREE_SIDE_EFFECTS (argarray[0])) argarray[0] = save_expr (argarray[0]); t = build_pointer_type (TREE_TYPE (fn)); @@ -6916,7 +6917,7 @@ build_special_member_call (tree instance, tree nam /* However, for assignment operators, we must convert dynamically if the base is virtual. */ instance = build_base_path (PLUS_EXPR, instance, - binfo, /*nonnull=*/1); + binfo, /*nonnull=*/1, complain); } } Index: cp/cvt.c =================================================================== --- cp/cvt.c (revision 179128) +++ cp/cvt.c (working copy) @@ -1,7 +1,7 @@ /* Language-level data type conversion for GNU C++. Copyright (C) 1987, 1988, 1992, 1993, 1994, 1995, 1996, 1997, 1998, - 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 - Free Software Foundation, Inc. + 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, + 2011 Free Software Foundation, Inc. Hacked by Michael Tiemann (tiemann@cygnus.com) This file is part of GCC. @@ -157,7 +157,8 @@ cp_convert_to_pointer (tree type, tree expr) if (binfo || same_p) { if (binfo) - expr = build_base_path (code, expr, binfo, 0); + expr = build_base_path (code, expr, binfo, 0, + tf_warning_or_error); /* Add any qualifier conversions. */ return build_nop (type, expr); } @@ -275,7 +276,8 @@ convert_to_pointer_force (tree type, tree expr) return error_mark_node; if (binfo) { - expr = build_base_path (code, expr, binfo, 0); + expr = build_base_path (code, expr, binfo, 0, + tf_warning_or_error); if (expr == error_mark_node) return error_mark_node; /* Add any qualifier conversions. */ @@ -341,7 +343,8 @@ build_up_reference (tree type, tree arg, int flags return error_mark_node; if (binfo == NULL_TREE) return error_not_base_type (target_type, argtype); - rval = build_base_path (PLUS_EXPR, rval, binfo, 1); + rval = build_base_path (PLUS_EXPR, rval, binfo, 1, + tf_warning_or_error); } else rval Index: cp/cp-tree.h =================================================================== --- cp/cp-tree.h (revision 179128) +++ cp/cp-tree.h (working copy) @@ -4790,7 +4790,7 @@ extern void validate_conversion_obstack (void); /* in class.c */ extern tree build_vfield_ref (tree, tree); extern tree build_base_path (enum tree_code, tree, - tree, int); + tree, int, tsubst_flags_t); extern tree convert_to_base (tree, tree, bool, bool, tsubst_flags_t); extern tree convert_to_base_statically (tree, tree);