From patchwork Fri May 31 09:52:28 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Eric Botcazou X-Patchwork-Id: 1108274 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-502057-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=adacore.com Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45Ffwl73LZz9sN6 for ; Fri, 31 May 2019 19:56:15 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; q=dns; s=default; b=cVEwrY5yUMb48yVV OT5IZXL+ZOtCNAy/VNWTsoGI+Rh1UrWSgtTrCs6aoQDY96fVxzP0lhy8N+H3ZT6m xaJ03PmRzpLTSATKIZrcP+RESD3A+U1odOTuYCLFF80R1pi5VvLOjfHdkr57cv4T hoGrjSLwOB2dV5sr2XBHzw65J8U= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:date:message-id:mime-version:content-type :content-transfer-encoding; s=default; bh=d3b0/AZJ4KbL9Sfbs2PM2v jwdAU=; b=YX4M3eg4Vv9qMbQaR3GGq9TTtANMu4hA6KetD4prj7Ik+JdqLI/iS9 HfX0neH2ceAYK1fmhoL6LR+lnERtgR3cqwy0bO2QN/7TlyuLIG9bwhQaMFB251Jv B49h/3wpgjppktUmfu8OLONLSIPzdyXyxhiWM6UWNDEW+w9EAVnoU= Received: (qmail 109925 invoked by alias); 31 May 2019 09:56:08 -0000 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 Received: (qmail 109917 invoked by uid 89); 31 May 2019 09:56:07 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-6.9 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.1 spammy=game, 271694, PLUS_EXPR, plus_expr X-HELO: smtp.eu.adacore.com Received: from mel.act-europe.fr (HELO smtp.eu.adacore.com) (194.98.77.210) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 31 May 2019 09:56:06 +0000 Received: from localhost (localhost [127.0.0.1]) by filtered-smtp.eu.adacore.com (Postfix) with ESMTP id ABFB581395 for ; Fri, 31 May 2019 11:56:03 +0200 (CEST) Received: from smtp.eu.adacore.com ([127.0.0.1]) by localhost (smtp.eu.adacore.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id Hj323_2vFDeC for ; Fri, 31 May 2019 11:56:03 +0200 (CEST) Received: from polaris.localnet (bon31-6-88-161-99-133.fbx.proxad.net [88.161.99.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.eu.adacore.com (Postfix) with ESMTPSA id 88B0F81392 for ; Fri, 31 May 2019 11:56:03 +0200 (CEST) From: Eric Botcazou To: gcc-patches@gcc.gnu.org Subject: [patch] Fix segfault caused by spurious constant overflow Date: Fri, 31 May 2019 11:52:28 +0200 Message-ID: <5613133.Bo1V3R3Yke@polaris> MIME-Version: 1.0 Hi, this is a regression present for 32-bit targets on mainline and 9 branch only, but the underlying issue dates back from the removal of the TYPE_IS_SIZETYPE machinery. Since the removal of this machinery, there is an internal conflict for sizetype: it's an unsigned type so with wrap-around semantics on overflow but overflow nevertheless needs to be tracked for it in order to avoid buffer overflows for large objects. The constant folder contains various tricks to that effect and the Ada front- end even more so, because VLAs are first-class citizens in the language and their lower bound is not necessarily 0. In particular, you need to be able to distinguish large constants in sizetype from small negative constants turned into even larger constants, because the latter appear in the length of e.g.: type Arr is array (2 .. N) of Long_Long_Integer; This works when the expressions haven't been too much mangled by the constant folder and here we have a counter-example for 32-bit targets. Starting with: (N + 4294967295) * 8 which is the sizetype expression of the size of Arr in bytes, extract_muldiv_1 distributes the multiplication: N * 8 + 4294967288 and, immediately after, fold_plusminus_mult_expr factors it back: (N + 536870911) * 8 At this point, there is no way for gigi to tell that it's the expression of a simple array with no overflow in sight because the 536870911 constant is large but not large enough, so gigi flags it as overflowing for small values of N. I don't see any other way out than disabling the back-and-forth mathematical game played by the constant folder in this case, which very likely brings no benefit in practice, hence the proposed fix. Tested on x86_64-suse-linux, OK for the mainline and 9 branch? 2019-05-31 Eric Botcazou * fold-const.c (extract_muldiv_1) : Do not distribute a multiplication by a power-of-two value. 2019-05-31 Eric Botcazou * gnat.dg/specs/discr6.ads: New test. Index: fold-const.c =================================================================== --- fold-const.c (revision 271694) +++ fold-const.c (working copy) @@ -6475,8 +6475,13 @@ extract_muldiv_1 (tree t, tree c, enum t apply the distributive law to commute the multiply and addition if the multiplication of the constants doesn't overflow and overflow is defined. With undefined overflow - op0 * c might overflow, while (op0 + orig_op1) * c doesn't. */ - if (code == MULT_EXPR && TYPE_OVERFLOW_WRAPS (ctype)) + op0 * c might overflow, while (op0 + orig_op1) * c doesn't. + But fold_plusminus_mult_expr would factor back any power-of-two + value so do not distribute in the first place in this case. */ + if (code == MULT_EXPR + && TYPE_OVERFLOW_WRAPS (ctype) + && !(tree_fits_shwi_p (c) + && exact_log2 (absu_hwi (tree_to_shwi (c))) > 0)) return fold_build2 (tcode, ctype, fold_build2 (code, ctype, fold_convert (ctype, op0),