From owner-svn-src-head@FreeBSD.ORG Tue Jan 27 18:04:42 2015 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 0B08A46F; Tue, 27 Jan 2015 18:04:42 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id EC390EB2; Tue, 27 Jan 2015 18:04:41 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.9/8.14.9) with ESMTP id t0RI4fA3072694; Tue, 27 Jan 2015 18:04:41 GMT (envelope-from se@FreeBSD.org) Received: (from se@localhost) by svn.freebsd.org (8.14.9/8.14.9/Submit) id t0RI4fbv072693; Tue, 27 Jan 2015 18:04:41 GMT (envelope-from se@FreeBSD.org) Message-Id: <201501271804.t0RI4fbv072693@svn.freebsd.org> X-Authentication-Warning: svn.freebsd.org: se set sender to se@FreeBSD.org using -f From: Stefan Esser Date: Tue, 27 Jan 2015 18:04:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r277798 - head/bin/expr X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 27 Jan 2015 18:04:42 -0000 Author: se Date: Tue Jan 27 18:04:41 2015 New Revision: 277798 URL: https://svnweb.freebsd.org/changeset/base/277798 Log: Fix overflow check for multiplication: - Add special test to detect the case of -1 * INTMAX_MIN - Protect against elimination of the test division by the optimizer Garrett Cooper noticed that the overflow checks were incomplete, and Bruce Evans suggested the use of the "volatile" qualifier to counter the effect of the undefined behaviour, when the prior multiplication caused overflow, and he also suggested improvements to the comments. Reviewed by: bde MFC after: 1 week Modified: head/bin/expr/expr.y Modified: head/bin/expr/expr.y ============================================================================== --- head/bin/expr/expr.y Tue Jan 27 17:46:55 2015 (r277797) +++ head/bin/expr/expr.y Tue Jan 27 18:04:41 2015 (r277798) @@ -444,14 +444,26 @@ op_minus(struct val *a, struct val *b) return (r); } +/* + * We depend on undefined behaviour giving a result (in r). + * To test this result, pass it as volatile. This prevents + * optimizing away of the test based on the undefined behaviour. + */ void -assert_times(intmax_t a, intmax_t b, intmax_t r) +assert_times(intmax_t a, intmax_t b, volatile intmax_t r) { /* - * if first operand is 0, no overflow is possible, - * else result of division test must match second operand + * If the first operand is 0, no overflow is possible, + * else the result of the division test must match the + * second operand. + * + * Be careful to avoid overflow in the overflow test, as + * in assert_div(). Overflow in division would kill us + * with a SIGFPE before getting the test wrong. In old + * buggy versions, optimization used to give a null test + * instead of a SIGFPE. */ - if (a != 0 && r / a != b) + if ((a == -1 && b == INTMAX_MIN) || (a != 0 && r / a != b)) errx(ERR_EXIT, "overflow"); }