From patchwork Fri Aug 28 16:54:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Jambor X-Patchwork-Id: 1353394 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=suse.cz Received: from sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4BdQgh2Spkz9sTK for ; Sat, 29 Aug 2020 02:54:55 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6C2F33861031; Fri, 28 Aug 2020 16:54:50 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by sourceware.org (Postfix) with ESMTPS id 951233857004 for ; Fri, 28 Aug 2020 16:54:47 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 951233857004 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=suse.cz Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mjambor@suse.cz X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 38D34AC12 for ; Fri, 28 Aug 2020 16:55:19 +0000 (UTC) From: Martin Jambor To: GCC Patches Subject: [PATCH] sra: Avoid SRAing if there is an aout-of-bounds access (PR 96820) User-Agent: Notmuch/0.30 (https://notmuchmail.org) Emacs/26.3 (x86_64-suse-linux-gnu) Date: Fri, 28 Aug 2020 18:54:45 +0200 Message-ID: MIME-Version: 1.0 X-Spam-Status: No, score=-3038.0 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Richard Biener Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" Hi, the testcase causes and ICE in the SRA verifier on x86_64 when compiling with -m32 because build_user_friendly_ref_for_offset looks at an out-of-bounds array_ref within an array_ref which accesses an offset which does not fit into a signed 32bit integer and turns it into an array-ref with a negative index. The best thing is probably to bail out early when encountering an out of bounds access to a local stack-allocated aggregate (and let the DSE just delete such statements) which is what the patch does. I also glanced over to the initial candidate vetting routine to make sure the size would fit into HWI and noticed that it uses unsigned variants whereas the rest of SRA operates on signed offsets and sizes (because get_ref_and_extent does) and so changed that for the sake of consistency. These ancient checks operate on sizes of types as opposed to DECLs but I hope that any issues potentially arising from that are basically hypothetical. Bootstrapped and tested on x86_64-linux. OK for master and then for gcc-10 branch? Thanks, Martin gcc/ChangeLog: 2020-08-28 Martin Jambor PR tree-optimization/96820 * tree-sra.c (create_access): Disqualify candidates with accesses beyond the end of the original aggregate. (maybe_add_sra_candidate): Check that candidate type size fits signed uhwi for the sake of consistency. gcc/testsuite/ChangeLog: 2020-08-28 Martin Jambor PR tree-optimization/96820 * gcc.dg/tree-ssa/pr96820.c: New test. --- gcc/testsuite/gcc.dg/tree-ssa/pr96820.c | 12 ++++++++++++ gcc/tree-sra.c | 9 +++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/pr96820.c diff --git a/gcc/testsuite/gcc.dg/tree-ssa/pr96820.c b/gcc/testsuite/gcc.dg/tree-ssa/pr96820.c new file mode 100644 index 00000000000..f5c2195f310 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/pr96820.c @@ -0,0 +1,12 @@ +/* { dg-do compile } */ +/* { dg-options "-O1" } */ + +struct a { + int b; +}; +int main() { + struct a d[][6] = {4}; + struct a e; + d[1955249013][1955249013] = e; + return e.b; +} diff --git a/gcc/tree-sra.c b/gcc/tree-sra.c index 754f41302fc..98a6cacbe2a 100644 --- a/gcc/tree-sra.c +++ b/gcc/tree-sra.c @@ -941,6 +941,11 @@ create_access (tree expr, gimple *stmt, bool write) disqualify_candidate (base, "Encountered an unconstrained access."); return NULL; } + if (offset + size > tree_to_shwi (DECL_SIZE (base))) + { + disqualify_candidate (base, "Encountered an access beyond the base."); + return NULL; + } access = create_access_1 (base, offset, size); access->expr = expr; @@ -1880,12 +1885,12 @@ maybe_add_sra_candidate (tree var) reject (var, "has incomplete type"); return false; } - if (!tree_fits_uhwi_p (TYPE_SIZE (type))) + if (!tree_fits_shwi_p (TYPE_SIZE (type))) { reject (var, "type size not fixed"); return false; } - if (tree_to_uhwi (TYPE_SIZE (type)) == 0) + if (tree_to_shwi (TYPE_SIZE (type)) == 0) { reject (var, "type size is zero"); return false;