From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 59155 invoked by alias); 1 Jun 2015 20:06:13 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 59145 invoked by uid 89); 1 Jun 2015 20:06:12 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.6 required=5.0 tests=AWL,BAYES_05,FREEMAIL_FROM,RCVD_IN_DNSWL_LOW,SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-wg0-f52.google.com Received: from mail-wg0-f52.google.com (HELO mail-wg0-f52.google.com) (74.125.82.52) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Mon, 01 Jun 2015 20:06:11 +0000 Received: by wgez8 with SMTP id z8so123398919wge.0 for ; Mon, 01 Jun 2015 13:06:08 -0700 (PDT) X-Received: by 10.194.250.98 with SMTP id zb2mr44616499wjc.90.1433189168437; Mon, 01 Jun 2015 13:06:08 -0700 (PDT) Received: from localhost ([95.144.14.193]) by mx.google.com with ESMTPSA id fs9sm23418896wjc.34.2015.06.01.13.06.06 (version=TLSv1.2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 01 Jun 2015 13:06:07 -0700 (PDT) From: Richard Sandiford To: Marek Polacek Mail-Followup-To: Marek Polacek ,GCC Patches , Jason Merrill , Joseph Myers , rdsandiford@googlemail.com Cc: GCC Patches , Jason Merrill , Joseph Myers Subject: Re: [C/C++ PATCH] Implement -Wshift-overflow (PR c++/55095) References: <20150525194816.GX27320@redhat.com> Date: Mon, 01 Jun 2015 20:06:00 -0000 In-Reply-To: <20150525194816.GX27320@redhat.com> (Marek Polacek's message of "Mon, 25 May 2015 21:48:16 +0200") Message-ID: <877frnchxt.fsf@googlemail.com> User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-SW-Source: 2015-06/txt/msg00112.txt.bz2 Marek Polacek writes: > + /* Left-hand operand must be signed. */ > + if (TYPE_UNSIGNED (type0)) > + return false; > + > + /* Compute the result in infinite precision math (sort of). */ > + widest_int w = wi::lshift (wi::to_widest (op0), wi::to_widest (op1)); > + unsigned int min_prec = wi::min_precision (w, SIGNED); > + /* Watch out for shifting a negative value. */ > + tree r = wide_int_to_tree (tree_int_cst_sgn (op0) >= 0 > + ? unsigned_type_for (type0) > + : type0, w); > + bool overflowed = wi::cmps (w, wi::to_widest (r)); > + if (overflowed && c_inhibit_evaluation_warnings == 0) > + warning_at (loc, OPT_Wshift_overflow, > + "result of %qE requires %u bits to represent, " > + "but %qT only has %u bits", > + build2_loc (loc, LSHIFT_EXPR, type0, op0, op1), > + min_prec, type0, TYPE_PRECISION (type0)); > + > + return overflowed; Yeah, this "sort of" is a bit worrying :-) Especially as the number of bits in a widest_int depends on the number of bits in the target's widest integer mode. E.g. for i386 it's forced to 128, but for ARM it's 512 (IIRC). Could you do the check based on the wi::min_precision of the unshifted value? I.e. see whether adding the shift amount to that gives a value greater than type's precision. Thanks, Richard