From patchwork Thu Jun 17 09:57:21 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shujing Zhao X-Patchwork-Id: 56001 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 A5799B7D80 for ; Thu, 17 Jun 2010 19:59:13 +1000 (EST) Received: (qmail 20147 invoked by alias); 17 Jun 2010 09:59:11 -0000 Received: (qmail 20124 invoked by uid 22791); 17 Jun 2010 09:59:08 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY X-Spam-Check-By: sourceware.org Received: from rcsinet10.oracle.com (HELO rcsinet10.oracle.com) (148.87.113.121) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Thu, 17 Jun 2010 09:59:01 +0000 Received: from acsinet15.oracle.com (acsinet15.oracle.com [141.146.126.227]) by rcsinet10.oracle.com (Switch-3.4.2/Switch-3.4.1) with ESMTP id o5H9wcgf021765 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 17 Jun 2010 09:58:40 GMT Received: from acsmt354.oracle.com (acsmt354.oracle.com [141.146.40.154]) by acsinet15.oracle.com (Switch-3.4.2/Switch-3.4.1) with ESMTP id o5H9wXGY017745; Thu, 17 Jun 2010 09:58:34 GMT Received: from abhmt009.oracle.com by acsmt355.oracle.com with ESMTP id 352183451276768629; Thu, 17 Jun 2010 02:57:09 -0700 Received: from dhcp-beijing-cdc-10-182-121-28.cn.oracle.com (/10.182.121.28) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 17 Jun 2010 02:57:09 -0700 Message-ID: <4C19F181.1050205@oracle.com> Date: Thu, 17 Jun 2010 17:57:21 +0800 From: Shujing Zhao User-Agent: Thunderbird 2.0.0.24 (X11/20100228) MIME-Version: 1.0 To: GCC Patches CC: Gabriel Dos Reis , Paolo Carlini Subject: Re: [PATCH, c++] Emit the diagnostic messages of convert_to_void References: <4C19DA81.1080807@oracle.com> <4C19E122.1010900@oracle.com> <4C19EEA3.4040601@oracle.com> In-Reply-To: <4C19EEA3.4040601@oracle.com> 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 On 06/17/2010 05:45 PM, Shujing Zhao wrote: > On 06/17/2010 04:47 PM, Shujing Zhao wrote: >> On 06/17/2010 04:19 PM, Shujing Zhao wrote: >>> Hi, >>> >>> This patch is to fix the diagnostic issues of function >>> convert_to_void, just like the previous one. >>> Tested on i686-pc-linux-gnu with no regression. >>> Is it ok for trunk? >>> >>> Thanks >>> Pearly >>> >> Sorry, send the wrong patch. > > Sorry, the attached patch is the right one. > I'm so sorry to send the patch again and again. Index: typeck.c =================================================================== --- typeck.c (revision 160871) +++ typeck.c (working copy) @@ -5589,7 +5589,7 @@ tree cp_build_compound_expr (tree lhs, tree rhs, tsubst_flags_t complain) { - lhs = convert_to_void (lhs, "left-hand operand of comma", complain); + lhs = convert_to_void (lhs, ICV_LEFT_OF_COMMA, complain); if (lhs == error_mark_node || rhs == error_mark_node) return error_mark_node; @@ -5856,7 +5856,7 @@ Any expression can be explicitly converted to type cv void. */ if (TREE_CODE (type) == VOID_TYPE) - return convert_to_void (expr, /*implicit=*/NULL, complain); + return convert_to_void (expr, ICV_NULL, complain); /* [expr.static.cast] Index: init.c =================================================================== --- init.c (revision 160871) +++ init.c (working copy) @@ -1375,7 +1375,7 @@ release_tree_vector (parms); if (TREE_SIDE_EFFECTS (rval)) - finish_expr_stmt (convert_to_void (rval, NULL, complain)); + finish_expr_stmt (convert_to_void (rval, ICV_NULL, complain)); } /* This function is responsible for initializing EXP with INIT @@ -2718,7 +2718,7 @@ /* Pre-evaluate the SAVE_EXPR outside of the BIND_EXPR. */ body = build2 (COMPOUND_EXPR, void_type_node, base, body); - return convert_to_void (body, /*implicit=*/NULL, tf_warning_or_error); + return convert_to_void (body, ICV_NULL, tf_warning_or_error); } /* Create an unnamed variable of the indicated TYPE. */ Index: semantics.c =================================================================== --- semantics.c (revision 160871) +++ semantics.c (working copy) @@ -608,10 +608,10 @@ { if (warn_sequence_point) verify_sequence_points (expr); - expr = convert_to_void (expr, "statement", tf_warning_or_error); + expr = convert_to_void (expr, ICV_STATEMENT, tf_warning_or_error); } else if (!type_dependent_expression_p (expr)) - convert_to_void (build_non_dependent_expr (expr), "statement", + convert_to_void (build_non_dependent_expr (expr), ICV_STATEMENT, tf_warning_or_error); if (check_for_bare_parameter_packs (expr)) @@ -869,11 +869,11 @@ { if (warn_sequence_point) verify_sequence_points (expr); - expr = convert_to_void (expr, "3rd expression in for", + expr = convert_to_void (expr, ICV_THIRD_IN_FOR, tf_warning_or_error); } else if (!type_dependent_expression_p (expr)) - convert_to_void (build_non_dependent_expr (expr), "3rd expression in for", + convert_to_void (build_non_dependent_expr (expr), ICV_THIRD_IN_FOR, tf_warning_or_error); expr = maybe_cleanup_point_expr_void (expr); if (check_for_bare_parameter_packs (expr)) Index: cvt.c =================================================================== --- cvt.c (revision 160871) +++ cvt.c (working copy) @@ -651,7 +651,7 @@ if (code == VOID_TYPE && (convtype & CONV_STATIC)) { - e = convert_to_void (e, /*implicit=*/NULL, tf_warning_or_error); + e = convert_to_void (e, ICV_NULL, tf_warning_or_error); return e; } @@ -814,19 +814,18 @@ make it impossible to ignore the reference return value from functions. We issue warnings in the confusing cases. - IMPLICIT is non-NULL iff an expression is being implicitly converted; it - is NULL when the user is explicitly converting an expression to void via - a cast. When non-NULL, IMPLICIT is a string indicating the context of - the implicit conversion. */ + The IMPLICIT is ICV_NULL when the user is explicitly converting an expression + to void via a cast. If an expression is being implicitly converted, IMPLICIT + indicates the context of the implicit conversion. */ tree -convert_to_void (tree expr, const char *implicit, tsubst_flags_t complain) +convert_to_void (tree expr, impl_conv_void implicit, tsubst_flags_t complain) { if (expr == error_mark_node || TREE_TYPE (expr) == error_mark_node) return error_mark_node; - if (implicit == NULL) + if (implicit == ICV_NULL) mark_exp_read (expr); else { @@ -865,12 +864,17 @@ tree op1 = TREE_OPERAND (expr,1); tree op2 = TREE_OPERAND (expr,2); bool side_effects = TREE_SIDE_EFFECTS (op1) || TREE_SIDE_EFFECTS (op2); - tree new_op1 = convert_to_void - (op1, (implicit && !side_effects - ? "second operand of conditional" : NULL), complain); - tree new_op2 = convert_to_void - (op2, (implicit && !side_effects - ? "third operand of conditional" : NULL), complain); + tree new_op1, new_op2; + if (implicit != ICV_NULL && !side_effects) + { + new_op1 = convert_to_void (op1, ICV_SECOND_OF_COND, complain); + new_op2 = convert_to_void (op2, ICV_THIRD_OF_COND, complain); + } + else + { + new_op1 = convert_to_void (op1, ICV_NULL, complain); + new_op2 = convert_to_void (op2, ICV_NULL, complain); + } expr = build3 (COND_EXPR, TREE_TYPE (new_op1), TREE_OPERAND (expr, 0), new_op1, new_op2); @@ -881,9 +885,11 @@ { /* The second part of a compound expr contains the value. */ tree op1 = TREE_OPERAND (expr,1); - tree new_op1 = convert_to_void - (op1, (implicit && !TREE_NO_WARNING (expr) - ? "right-hand operand of comma" : NULL), complain); + tree new_op1; + if (implicit != ICV_NULL && !TREE_NO_WARNING (expr)) + new_op1 = convert_to_void (op1, ICV_RIGHT_OF_COMMA, complain); + else + new_op1 = convert_to_void (op1, ICV_NULL, complain); if (new_op1 != op1) { @@ -915,17 +921,88 @@ if (is_volatile && !is_complete) { if (complain & tf_warning) - warning (0, "object of incomplete type %qT will not be accessed in %s", - type, implicit ? implicit : "void context"); + switch (implicit) + { + case ICV_NULL: + warning (0, "object of incomplete type %qT will not " + "be accessed in void context", type); + break; + case ICV_SECOND_OF_COND: + warning (0, "object of incomplete type %qT will not " + "be accessed in second operand of conditional", + type); + break; + case ICV_THIRD_OF_COND: + warning (0, "object of incomplete type %qT will not " + "be accessed in third operand of conditional", + type); + break; + case ICV_RIGHT_OF_COMMA: + warning (0, "object of incomplete type %qT will not " + "be accessed in right-hand operand of comma", + type); + break; + case ICV_LEFT_OF_COMMA: + warning (0, "object of incomplete type %qT will not " + "be accessed in left-hand operand of comma", + type); + break; + case ICV_STATEMENT: + warning (0, "object of incomplete type %qT will not " + "be accessed in statement", type); + break; + case ICV_THIRD_IN_FOR: + warning (0, "object of incomplete type %qT will not " + "be accessed in 3rd expression in for ", + type); + break; + default: + gcc_unreachable (); + } } /* Don't load the value if this is an implicit dereference, or if the type needs to be handled by ctors/dtors. */ else if (is_volatile && (is_reference || TREE_ADDRESSABLE (type))) { if (complain & tf_warning) - warning (0, "object of type %qT will not be accessed in %s", - TREE_TYPE (TREE_OPERAND (expr, 0)), - implicit ? implicit : "void context"); + switch (implicit) + { + case ICV_NULL: + warning (0, "object of type %qT will not " + "be accessed in void context", type); + break; + case ICV_SECOND_OF_COND: + warning (0, "object of type %qT will not " + "be accessed in second operand of conditional", + type); + break; + case ICV_THIRD_OF_COND: + warning (0, "object of type %qT will not " + "be accessed in third operand of conditional", + type); + break; + case ICV_RIGHT_OF_COMMA: + warning (0, "object of type %qT will not " + "be accessed in right-hand operand of comma", + type); + break; + case ICV_LEFT_OF_COMMA: + warning (0, "object of type %qT will not " + "be accessed in left-hand operand of comma", + type); + break; + case ICV_STATEMENT: + warning (0, "object of type %qT will not " + "be accessed in statement", type); + break; + case ICV_THIRD_IN_FOR: + warning (0, "object of type %qT will not " + "be accessed in 3rd expression in for ", + type); + break; + default: + gcc_unreachable (); + } } if (is_reference || !is_volatile || !is_complete || TREE_ADDRESSABLE (type)) { @@ -936,7 +1013,7 @@ - automatic dereferencing of references, since the user cannot control it. (See also warn_if_unused_value() in stmt.c.) */ if (warn_unused_value - && implicit + && implicit != ICV_NULL && (complain & tf_warning) && !TREE_NO_WARNING (expr) && !is_reference) @@ -954,8 +1031,45 @@ int is_complete = COMPLETE_TYPE_P (complete_type (type)); if (TYPE_VOLATILE (type) && !is_complete && (complain & tf_warning)) - warning (0, "object %qE of incomplete type %qT will not be accessed in %s", - expr, type, implicit ? implicit : "void context"); + switch (implicit) + { + case ICV_NULL: + warning (0, "object %qE of incomplete type %qT will not " + "be accessed in void context", expr, type); + break; + case ICV_SECOND_OF_COND: + warning (0, "object %qE of incomplete type %qT will not " + "be accessed in second operand of conditional", + expr, type); + break; + case ICV_THIRD_OF_COND: + warning (0, "object %qE of incomplete type %qT will not " + "be accessed in third operand of conditional", + expr, type); + break; + case ICV_RIGHT_OF_COMMA: + warning (0, "object %qE of incomplete type %qT will not " + "be accessed in right-hand operand of comma", + expr, type); + break; + case ICV_LEFT_OF_COMMA: + warning (0, "object %qE of incomplete type %qT will not " + "be accessed in left-hand operand of comma", + expr, type); + break; + case ICV_STATEMENT: + warning (0, "object %qE of incomplete type %qT will not " + "be accessed in statement", expr, type); + break; + case ICV_THIRD_IN_FOR: + warning (0, "object %qE of incomplete type %qT will not " + "be accessed in 3rd expression in for ", + expr, type); + break; + default: + gcc_unreachable (); + } + break; } @@ -994,18 +1108,81 @@ /* [over.over] enumerates the places where we can take the address of an overloaded function, and this is not one of them. */ if (complain & tf_error) - error ("%s cannot resolve address of overloaded function", - implicit ? implicit : "void cast"); + switch (implicit) + { + case ICV_NULL: + error ("void cast " + "cannot resolve address of overloaded function"); + break; + case ICV_SECOND_OF_COND: + error ("second operand of conditional " + "cannot resolve address of overloaded function"); + break; + case ICV_THIRD_OF_COND: + error ("third operand of conditional " + "cannot resolve address of overloaded function"); + break; + case ICV_RIGHT_OF_COMMA: + error ("right-hand operand of comma " + "cannot resolve address of overloaded function"); + break; + case ICV_LEFT_OF_COMMA: + error ("left-hand operand of comma " + "cannot resolve address of overloaded function"); + break; + case ICV_STATEMENT: + error ("statement " + "cannot resolve address of overloaded function"); + break; + case ICV_THIRD_IN_FOR: + error ("3rd expression in for " + "cannot resolve address of overloaded function"); + break; + } else return error_mark_node; expr = void_zero_node; } - else if (implicit && probe == expr && is_overloaded_fn (probe)) + else if (implicit != ICV_NULL && probe == expr && is_overloaded_fn (probe)) { /* Only warn when there is no &. */ if (complain & tf_warning) - warning (OPT_Waddress, "%s is a reference, not call, to function %qE", - implicit, expr); + switch (implicit) + { + case ICV_SECOND_OF_COND: + warning (OPT_Waddress, + "second operand of conditional " + "is a reference, not call, to function %qE", expr); + break; + case ICV_THIRD_OF_COND: + warning (OPT_Waddress, + "third operand of conditional " + "is a reference, not call, to function %qE", expr); + break; + case ICV_RIGHT_OF_COMMA: + warning (OPT_Waddress, + "right-hand operand of comma " + "is a reference, not call, to function %qE", expr); + break; + case ICV_LEFT_OF_COMMA: + warning (OPT_Waddress, + "left-hand operand of comma " + "is a reference, not call, to function %qE", expr); + break; + case ICV_STATEMENT: + warning (OPT_Waddress, + "statement " + "is a reference, not call, to function %qE", expr); + break; + case ICV_THIRD_IN_FOR: + warning (OPT_Waddress, + "3rd expression in for " + "is a reference, not call, to function %qE", expr); + break; + default: + gcc_unreachable (); + } + if (TREE_CODE (expr) == COMPONENT_REF) expr = TREE_OPERAND (expr, 0); } @@ -1013,7 +1190,7 @@ if (expr != error_mark_node && !VOID_TYPE_P (TREE_TYPE (expr))) { - if (implicit + if (implicit != ICV_NULL && warn_unused_value && !TREE_NO_WARNING (expr) && !processing_template_decl) @@ -1022,7 +1199,35 @@ been explicitly cast to void, so we must do so here. */ if (!TREE_SIDE_EFFECTS (expr)) { if (complain & tf_warning) - warning (OPT_Wunused_value, "%s has no effect", implicit); + switch (implicit) + { + case ICV_SECOND_OF_COND: + warning (OPT_Wunused_value, + "second operand of conditional has no effect"); + break; + case ICV_THIRD_OF_COND: + warning (OPT_Wunused_value, + "third operand of conditional has no effect"); + break; + case ICV_RIGHT_OF_COMMA: + warning (OPT_Wunused_value, + "right-hand operand of comma has no effect"); + break; + case ICV_LEFT_OF_COMMA: + warning (OPT_Wunused_value, + "left-hand operand of comma has no effect"); + break; + case ICV_STATEMENT: + warning (OPT_Wunused_value, + "statement has no effect"); + break; + case ICV_THIRD_IN_FOR: + warning (OPT_Wunused_value, + "3rd expression in for has no effect"); + break; + default: + gcc_unreachable (); + } } else { Index: cp-tree.h =================================================================== --- cp-tree.h (revision 160871) +++ cp-tree.h (working copy) @@ -435,6 +435,17 @@ ICR_ASSIGN /* assignment */ } impl_conv_rhs; +/* Possible cases of implicit or explicit bad conversions to void. */ +typedef enum impl_conv_void { + ICV_NULL, /* NULL */ + ICV_SECOND_OF_COND, /* second operand of conditional */ + ICV_THIRD_OF_COND, /* third operand of conditional */ + ICV_RIGHT_OF_COMMA, /* right-hand operand of comma */ + ICV_LEFT_OF_COMMA, /* left-hand operand of comma */ + ICV_STATEMENT, /* statement */ + ICV_THIRD_IN_FOR /* 3rd expression in for */ +} impl_conv_void; + /* Macros for access to language-specific slots in an identifier. */ #define IDENTIFIER_NAMESPACE_BINDINGS(NODE) \ @@ -4669,8 +4680,8 @@ extern tree cp_convert (tree, tree); extern tree cp_convert_and_check (tree, tree); extern tree cp_fold_convert (tree, tree); -extern tree convert_to_void (tree, const char */*implicit context*/, - tsubst_flags_t); +extern tree convert_to_void (tree, impl_conv_void, + tsubst_flags_t); extern tree convert_force (tree, tree, int); extern tree build_expr_type_conversion (int, tree, bool); extern tree type_promotes_to (tree);