From patchwork Tue Jan 8 20:04:03 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jakub Jelinek X-Patchwork-Id: 210489 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 94A1A2C009B for ; Wed, 9 Jan 2013 07:04:25 +1100 (EST) Comment: DKIM? See http://www.dkim.org DKIM-Signature: v=1; a=rsa-sha1; c=relaxed/relaxed; d=gcc.gnu.org; s=default; x=1358280265; h=Comment: DomainKey-Signature:Received:Received:Received:Received:Received: Received:Received:Date:From:To:Cc:Subject:Message-ID:Reply-To: MIME-Version:Content-Type:Content-Disposition:User-Agent: Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive: List-Post:List-Help:Sender:Delivered-To; bh=Vn4g3Tu37QPOz94ARoUY /N32dNI=; b=GMYiPptNL+TMj+lnhIULTPwW2xU7PXOWoJ1mgZ8Pc0crKniiPBCF LJNFjoOZ0UuYuyQ1fKxqgD5bWxj3biUuuFi2xAs1ADmaYdrUtVpaRzh98lSG2nmn Tx/mpHBF7MennyUQ3QphkKs7nyjAUdpgZ29qA+s5EcVZkgUd5+e1Cbg= Comment: DomainKeys? See http://antispam.yahoo.com/domainkeys DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=default; d=gcc.gnu.org; h=Received:Received:X-SWARE-Spam-Status:X-Spam-Check-By:Received:Received:Received:Received:Received:Date:From:To:Cc:Subject:Message-ID:Reply-To:MIME-Version:Content-Type:Content-Disposition:User-Agent:X-IsSubscribed:Mailing-List:Precedence:List-Id:List-Unsubscribe:List-Archive:List-Post:List-Help:Sender:Delivered-To; b=fFJQnuClPHAsqFAcst7FspO6ppIpTwIZ7K46sLral36K/ngkTO6gF2YxmXZY7Q zBI4UNFjjqfLf0SypJoDY1+y8RrSDQu4JdIA1AFq1TVPmr5BX3f6ZHJEpcqSwUv8 12ssfhxO0QQL2Bcpl7NyNWCknOa/t/6rQ/7LDQkSTYxrc=; Received: (qmail 31125 invoked by alias); 8 Jan 2013 20:04:16 -0000 Received: (qmail 31117 invoked by uid 22791); 8 Jan 2013 20:04:15 -0000 X-SWARE-Spam-Status: No, hits=-6.4 required=5.0 tests=AWL, BAYES_00, KHOP_RCVD_UNTRUST, RCVD_IN_DNSWL_HI, RCVD_IN_HOSTKARMA_W, RP_MATCHES_RCVD, SPF_HELO_PASS 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; Tue, 08 Jan 2013 20:04:09 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id r08K46T4002962 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Tue, 8 Jan 2013 15:04:07 -0500 Received: from zalov.redhat.com (vpn1-5-98.ams2.redhat.com [10.36.5.98]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id r08K44D1022120 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Tue, 8 Jan 2013 15:04:06 -0500 Received: from zalov.cz (localhost [127.0.0.1]) by zalov.redhat.com (8.14.5/8.14.5) with ESMTP id r08K44KA031620; Tue, 8 Jan 2013 21:04:04 +0100 Received: (from jakub@localhost) by zalov.cz (8.14.5/8.14.5/Submit) id r08K435x031619; Tue, 8 Jan 2013 21:04:03 +0100 Date: Tue, 8 Jan 2013 21:04:03 +0100 From: Jakub Jelinek To: "Joseph S. Myers" , Jason Merrill Cc: gcc-patches@gcc.gnu.org Subject: [C/C++ PATCH] shift with negative or too big count warning (PR c/48418) Message-ID: <20130108200403.GN7269@tucnak.redhat.com> Reply-To: Jakub Jelinek MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) 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 discussed in the PR, on the following testcase we've regressed with the introduction of c_fully_fold, when the C FE normally warns the argument isn't folded yet. Fixed by also warning in c_fully_fold_internal, if before that function the shift count wasn't INTEGER_CST and after it it is. The testcase also revealed a regression on the C++ FE side, caused by SIZEOF_EXPR folding deferral. Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk? 2013-01-08 Jakub Jelinek PR c/48418 * c-common.c (c_fully_fold_internal): Warn for LSHIFT_EXPR and RSHIFT_EXPR, if orig_op1 isn't INTEGER_CST, op1 is INTEGER_CST and is either negative or bigger or equal to type precision of the first operand. * typeck.c (cp_build_binary_op): For LSHIFT_EXPR and RSHIFT_EXPR, call maybe_constant_value for the negative or too big shift count warnings. * c-c++-common/pr48418.c: New test. Jakub --- gcc/c-family/c-common.c.jj 2012-12-31 15:05:45.000000000 +0100 +++ gcc/c-family/c-common.c 2013-01-08 15:15:47.019347593 +0100 @@ -1269,6 +1269,25 @@ c_fully_fold_internal (tree expr, bool i && !TREE_OVERFLOW_P (op0) && !TREE_OVERFLOW_P (op1)) overflow_warning (EXPR_LOCATION (expr), ret); + if ((code == LSHIFT_EXPR || code == RSHIFT_EXPR) + && TREE_CODE (orig_op1) != INTEGER_CST + && TREE_CODE (op1) == INTEGER_CST + && (TREE_CODE (TREE_TYPE (orig_op0)) == INTEGER_TYPE + || TREE_CODE (TREE_TYPE (orig_op0)) == FIXED_POINT_TYPE) + && TREE_CODE (TREE_TYPE (orig_op1)) == INTEGER_TYPE + && c_inhibit_evaluation_warnings == 0) + { + if (tree_int_cst_sgn (op1) < 0) + warning_at (loc, 0, (code == LSHIFT_EXPR + ? "left shift count is negative" + : "right shift count is negative")); + else if (compare_tree_int (op1, + TYPE_PRECISION (TREE_TYPE (orig_op0))) + >= 0) + warning_at (loc, 0, (code == LSHIFT_EXPR + ? "left shift count >= width of type" + : "right shift count >= width of type")); + } goto out; case INDIRECT_REF: --- gcc/cp/typeck.c.jj 2013-01-07 14:14:44.000000000 +0100 +++ gcc/cp/typeck.c 2013-01-08 15:30:20.202388635 +0100 @@ -4095,10 +4095,13 @@ cp_build_binary_op (location_t location, } else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) { + tree const_op1 = maybe_constant_value (op1); + if (TREE_CODE (const_op1) != INTEGER_CST) + const_op1 = op1; result_type = type0; - if (TREE_CODE (op1) == INTEGER_CST) + if (TREE_CODE (const_op1) == INTEGER_CST) { - if (tree_int_cst_lt (op1, integer_zero_node)) + if (tree_int_cst_lt (const_op1, integer_zero_node)) { if ((complain & tf_warning) && c_inhibit_evaluation_warnings == 0) @@ -4106,7 +4109,7 @@ cp_build_binary_op (location_t location, } else { - if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0 + if (compare_tree_int (const_op1, TYPE_PRECISION (type0)) >= 0 && (complain & tf_warning) && c_inhibit_evaluation_warnings == 0) warning (0, "right shift count >= width of type"); @@ -4138,16 +4141,20 @@ cp_build_binary_op (location_t location, } else if (code0 == INTEGER_TYPE && code1 == INTEGER_TYPE) { + tree const_op1 = maybe_constant_value (op1); + if (TREE_CODE (const_op1) != INTEGER_CST) + const_op1 = op1; result_type = type0; - if (TREE_CODE (op1) == INTEGER_CST) + if (TREE_CODE (const_op1) == INTEGER_CST) { - if (tree_int_cst_lt (op1, integer_zero_node)) + if (tree_int_cst_lt (const_op1, integer_zero_node)) { if ((complain & tf_warning) && c_inhibit_evaluation_warnings == 0) warning (0, "left shift count is negative"); } - else if (compare_tree_int (op1, TYPE_PRECISION (type0)) >= 0) + else if (compare_tree_int (const_op1, + TYPE_PRECISION (type0)) >= 0) { if ((complain & tf_warning) && c_inhibit_evaluation_warnings == 0) --- gcc/testsuite/c-c++-common/pr48418.c.jj 2013-01-08 15:25:36.501003969 +0100 +++ gcc/testsuite/c-c++-common/pr48418.c 2013-01-08 15:21:54.000000000 +0100 @@ -0,0 +1,20 @@ +/* PR c/48418 */ +/* { dg-do compile } */ +/* { dg-options "-Wall -O2" } */ + +int +foo (int x) +{ + const int a = sizeof (int) * __CHAR_BIT__; + const int b = -7; + int c = 0; + c += x << a; /* { dg-warning "left shift count >= width of type" } */ + c += x << b; /* { dg-warning "left shift count is negative" } */ + c += x << (sizeof (int) * __CHAR_BIT__); /* { dg-warning "left shift count >= width of type" } */ + c += x << -7; /* { dg-warning "left shift count is negative" } */ + c += x >> a; /* { dg-warning "right shift count >= width of type" } */ + c += x >> b; /* { dg-warning "right shift count is negative" } */ + c += x >> (sizeof (int) * __CHAR_BIT__); /* { dg-warning "right shift count >= width of type" } */ + c += x >> -7; /* { dg-warning "right shift count is negative" } */ + return c; +}