From patchwork Thu Jun 17 08:19:13 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shujing Zhao X-Patchwork-Id: 55984 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 2DA331007D3 for ; Thu, 17 Jun 2010 18:20:53 +1000 (EST) Received: (qmail 18335 invoked by alias); 17 Jun 2010 08:20:48 -0000 Received: (qmail 18311 invoked by uid 22791); 17 Jun 2010 08:20:39 -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 08:20:29 +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 o5H8KLOe027327 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Thu, 17 Jun 2010 08:20:23 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 o5H7jVUS004305; Thu, 17 Jun 2010 08:20:21 GMT Received: from abhmt008.oracle.com by acsmt355.oracle.com with ESMTP id 333511111276762741; Thu, 17 Jun 2010 01:19:01 -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 01:19:00 -0700 Message-ID: <4C19DA81.1080807@oracle.com> Date: Thu, 17 Jun 2010 16:19:13 +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: [PATCH, c++] Emit the diagnostic messages of convert_to_void 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, 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 2010-06-17 Shujing Zhao * cp-tree.h (impl_conv_void): New type. (convert_to_void): Adjust prototype. * cvt.h (convert_to_void): Use impl_conv_void and emit the diagnostic for easy translation. Change caller. Index: cvt.c =================================================================== --- cvt.c (revision 160644) +++ cvt.c (working copy) @@ -814,19 +814,18 @@ ocp_convert (tree type, tree expr, int c 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 @@ convert_to_void (tree expr, const char * 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 @@ convert_to_void (tree expr, const char * { /* 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 @@ convert_to_void (tree expr, const char * 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 @@ convert_to_void (tree expr, const char * - 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 @@ convert_to_void (tree expr, const char * 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 @@ convert_to_void (tree expr, const char * /* [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 != IRC_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 @@ convert_to_void (tree expr, const char * 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 @@ convert_to_void (tree expr, const char * 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 160644) +++ cp-tree.h (working copy) @@ -435,6 +435,17 @@ typedef enum impl_conv_rhs { 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 ocp_convert (tree, tree, 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);