From patchwork Wed Jul 26 11:35:03 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marek Polacek X-Patchwork-Id: 793881 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-459004-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="vb18qFk1"; dkim-atps=neutral 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 3xHY224QY9z9rvt for ; Wed, 26 Jul 2017 21:35:21 +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:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; q=dns; s=default; b=b/ZH4veqz93CAM/2G hSikaXHrZVD0LKvLg761TCBkEd5QtZFsjlJGLG0iNSQRvaiUTyMkgN4l+waeJCRv NlLKxdtqalRBuG8p7wYa/5jGpDLLd64riSVHsArVdfptjaDJ0P0iSbR3dfl0YNBo g6kThnU0yP5OKGovWySfJyRpk4= 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:date :from:to:cc:subject:message-id:references:mime-version :content-type:in-reply-to; s=default; bh=JZONFdXF7Vonwu+BV+cc+ye anWw=; b=vb18qFk1RsxaJmI1BE53m2Z2DG5srWcCYJmuRtRcPJGftR1cQ3gB2kS nHVuNDFoBigB5I/w5uhHabb+OkpJ3w5U2kJd+MCNPNgdbOdnBe3DoPZm4FnyR3AB YCi7XAwrI4NZtQtCUI9Sa3aykNs/4rBg6CwjypxVrbVu1oeP14dg= Received: (qmail 101733 invoked by alias); 26 Jul 2017 11:35:12 -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 100244 invoked by uid 89); 26 Jul 2017 11:35:11 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, KAM_LAZY_DOMAIN_SECURITY, RP_MATCHES_RCVD, SPF_HELO_PASS autolearn=ham version=3.3.2 spammy= X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 26 Jul 2017 11:35:09 +0000 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.phx2.redhat.com [10.5.11.15]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 904EA272AF; Wed, 26 Jul 2017 11:35:07 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 904EA272AF Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx10.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=polacek@redhat.com Received: from redhat.com (ovpn-204-38.brq.redhat.com [10.40.204.38]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 46B6C6FE6B; Wed, 26 Jul 2017 11:35:06 +0000 (UTC) Date: Wed, 26 Jul 2017 13:35:03 +0200 From: Marek Polacek To: Richard Biener Cc: Eric Botcazou , GCC Patches Subject: Re: [PATCH] Fix infinite recursion with div-by-zero (PR middle-end/70992) Message-ID: <20170726113503.GI3397@redhat.com> References: <20170718160511.GP2890@redhat.com> <20170725121937.GF3397@redhat.com> <1771717.3h9EB9PvgT@arcturus.home> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.8.3 (2017-05-23) On Tue, Jul 25, 2017 at 03:47:31PM +0200, Richard Biener wrote: > On Tue, Jul 25, 2017 at 3:30 PM, Eric Botcazou wrote: > >> Eric, any comments? > > > > No objection for the build2_stat hunk, I think it's in keeping with the Ada > > semantics. But the tree_could_trap_p hunk is certainly an abomination... > > > >> We could also avoid tree_could_trap_p by special-casing only > >> *_DIV_EXPR and *_MOD_EXPR > >> with integer zero 2nd operand explicitely in build2 given there's no > >> "constant" value for this. That is, > >> for FP 1./0. is NaN (a "constant" value) even if the operation might trap. > > > > Yes, that would be faster & simpler and avoids the abomination. > > Ok, then let's go with that slightly uglier but less abominal variant ;) Like this then? Bootstrapped/regtested on x86_64-linux (including Ada) and powerpc64le-unknown-linux-gnu, ok for trunk? 2017-07-26 Marek Polacek PR middle-end/70992 * tree.c (build2_stat): Don't set TREE_CONSTANT on divisions by zero. * gcc.dg/overflow-warn-1.c: Adjust dg-error. * gcc.dg/overflow-warn-2.c: Likewise. * gcc.dg/overflow-warn-3.c: Likewise. * gcc.dg/overflow-warn-4.c: Likewise. * gcc.dg/torture/pr70992-2.c: New test. * gcc.dg/torture/pr70992.c: New test. Marek diff --git gcc/testsuite/gcc.dg/overflow-warn-1.c gcc/testsuite/gcc.dg/overflow-warn-1.c index 8eb322579cf..a5cd5738636 100644 --- gcc/testsuite/gcc.dg/overflow-warn-1.c +++ gcc/testsuite/gcc.dg/overflow-warn-1.c @@ -49,7 +49,7 @@ static int sc = INT_MAX + 1; /* { dg-warning "25:integer overflow in expression" void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */ /* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } .-1 } */ void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */ -/* { dg-error "initializer element is not computable at load time" "constant" { target *-*-* } .-1 } */ +/* { dg-error "initializer element is not constant" "constant" { target *-*-* } .-1 } */ /* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */ void *r = (1 ? 0 : INT_MAX+1); diff --git gcc/testsuite/gcc.dg/overflow-warn-2.c gcc/testsuite/gcc.dg/overflow-warn-2.c index f048d6dae2a..05ab104fa4a 100644 --- gcc/testsuite/gcc.dg/overflow-warn-2.c +++ gcc/testsuite/gcc.dg/overflow-warn-2.c @@ -49,7 +49,7 @@ static int sc = INT_MAX + 1; /* { dg-warning "integer overflow in expression" } void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } */ /* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } .-1 } */ void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */ -/* { dg-error "initializer element is not computable at load time" "constant" { target *-*-* } .-1 } */ +/* { dg-error "initializer element is not constant" "constant" { target *-*-* } .-1 } */ /* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */ void *r = (1 ? 0 : INT_MAX+1); diff --git gcc/testsuite/gcc.dg/overflow-warn-3.c gcc/testsuite/gcc.dg/overflow-warn-3.c index 664011e401d..fd4a34f67e2 100644 --- gcc/testsuite/gcc.dg/overflow-warn-3.c +++ gcc/testsuite/gcc.dg/overflow-warn-3.c @@ -55,7 +55,7 @@ void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } /* { dg-warning "overflow in constant expression" "constant" { target *-*-* } .-1 } */ /* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */ void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */ -/* { dg-error "initializer element is not computable at load time" "constant" { target *-*-* } .-1 } */ +/* { dg-error "initializer element is not constant" "constant" { target *-*-* } .-1 } */ /* { dg-warning "initialization makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */ void *r = (1 ? 0 : INT_MAX+1); diff --git gcc/testsuite/gcc.dg/overflow-warn-4.c gcc/testsuite/gcc.dg/overflow-warn-4.c index 52677ce897a..018e3e1e4cd 100644 --- gcc/testsuite/gcc.dg/overflow-warn-4.c +++ gcc/testsuite/gcc.dg/overflow-warn-4.c @@ -55,7 +55,7 @@ void *p = 0 * (INT_MAX + 1); /* { dg-warning "integer overflow in expression" } /* { dg-error "overflow in constant expression" "constant" { target *-*-* } .-1 } */ /* { dg-error "initialization makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */ void *q = 0 * (1 / 0); /* { dg-warning "division by zero" } */ -/* { dg-error "initializer element is not computable at load time" "constant" { target *-*-* } .-1 } */ +/* { dg-error "initializer element is not constant" "constant" { target *-*-* } .-1 } */ /* { dg-error "initialization makes pointer from integer without a cast" "null" { target *-*-* } .-2 } */ void *r = (1 ? 0 : INT_MAX+1); diff --git gcc/testsuite/gcc.dg/torture/pr70992-2.c gcc/testsuite/gcc.dg/torture/pr70992-2.c index e69de29bb2d..c5d2c5f2683 100644 --- gcc/testsuite/gcc.dg/torture/pr70992-2.c +++ gcc/testsuite/gcc.dg/torture/pr70992-2.c @@ -0,0 +1,9 @@ +/* PR middle-end/70992 */ +/* { dg-do compile } */ + +unsigned int *od; +int +fn (void) +{ + return (0 % 0 + 1) * *od * 2; /* { dg-warning "division by zero" } */ +} diff --git gcc/testsuite/gcc.dg/torture/pr70992.c gcc/testsuite/gcc.dg/torture/pr70992.c index e69de29bb2d..56728e09d1b 100644 --- gcc/testsuite/gcc.dg/torture/pr70992.c +++ gcc/testsuite/gcc.dg/torture/pr70992.c @@ -0,0 +1,41 @@ +/* PR middle-end/70992 */ +/* { dg-do compile } */ + +typedef unsigned int uint32_t; +typedef int int32_t; + +uint32_t +fn (uint32_t so) +{ + return (so + so) * (0x80000000 / 0 + 1); /* { dg-warning "division by zero" } */ +} + +uint32_t +fn5 (uint32_t so) +{ + return (0x80000000 / 0 + 1) * (so + so); /* { dg-warning "division by zero" } */ +} + +uint32_t +fn6 (uint32_t so) +{ + return (0x80000000 / 0 - 1) * (so + so); /* { dg-warning "division by zero" } */ +} + +uint32_t +fn2 (uint32_t so) +{ + return (so + so) * (0x80000000 / 0 - 1); /* { dg-warning "division by zero" } */ +} + +int32_t +fn3 (int32_t so) +{ + return (so + so) * (0x80000000 / 0 + 1); /* { dg-warning "division by zero" } */ +} + +int32_t +fn4 (int32_t so) +{ + return (so + so) * (0x80000000 / 0 - 1); /* { dg-warning "division by zero" } */ +} diff --git gcc/tree.c gcc/tree.c index b7de2840ac6..48fb2ce0651 100644 --- gcc/tree.c +++ gcc/tree.c @@ -4456,7 +4456,7 @@ build1_stat (enum tree_code code, tree type, tree node MEM_STAT_DECL) tree build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL) { - bool constant, read_only, side_effects; + bool constant, read_only, side_effects, div_by_zero; tree t; gcc_assert (TREE_CODE_LENGTH (code) == 2); @@ -4489,6 +4489,23 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL) read_only = 1; side_effects = TREE_SIDE_EFFECTS (t); + switch (code) + { + case TRUNC_DIV_EXPR: + case CEIL_DIV_EXPR: + case FLOOR_DIV_EXPR: + case ROUND_DIV_EXPR: + case EXACT_DIV_EXPR: + case CEIL_MOD_EXPR: + case FLOOR_MOD_EXPR: + case ROUND_MOD_EXPR: + case TRUNC_MOD_EXPR: + div_by_zero = integer_zerop (arg1); + break; + default: + div_by_zero = false; + } + PROCESS_ARG (0); PROCESS_ARG (1); @@ -4505,7 +4522,8 @@ build2_stat (enum tree_code code, tree tt, tree arg0, tree arg1 MEM_STAT_DECL) else { TREE_READONLY (t) = read_only; - TREE_CONSTANT (t) = constant; + /* Don't mark X / 0 as constant. */ + TREE_CONSTANT (t) = constant && !div_by_zero; TREE_THIS_VOLATILE (t) = (TREE_CODE_CLASS (code) == tcc_reference && arg0 && TREE_THIS_VOLATILE (arg0));