From patchwork Tue Apr 25 08:23:13 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Arnaud Charlet X-Patchwork-Id: 754636 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 3wBx754HScz9s85 for ; Tue, 25 Apr 2017 18:23:27 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="SxSDwRx7"; dkim-atps=neutral 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:mime-version:content-type; q=dns; s=default; b=ITujxuWp6gV+GImmsD/HeAT5dC0q/ExxD2207Ftu/4kKLyUFZv zkvgFguE7O1LARsAhTbvnWhGpaJsMEazLSktDEdkYa3GTO/ualI4xLp06rFU5+0A B9YRyJdFXJh0pZFR3N7a8v1vOMUaCkNTAbQI3htoZkG+aBAj/GcWsyJY8= 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:mime-version:content-type; s= default; bh=Uwq7e6SzF+Y0qkx281sBgDntJBw=; b=SxSDwRx7ptd9lSCx4lUL uY7UtL2/T824K4jXmy7KvJSKNugBHtBbWTP34hmYcJ6Fnia1CEgBhrQw5KIptQSc mHPdbNhC4c/TzdWLAP1rnal2bdGTyfJQZ+LZvewraGdX/A9RcIXbu7VPEPzU3jr0 XdtXkj4TFo2xEo7g5BZa4RY= Received: (qmail 64305 invoked by alias); 25 Apr 2017 08:23:16 -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 61668 invoked by uid 89); 25 Apr 2017 08:23:14 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-11.1 required=5.0 tests=BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=powers, ctrl, modulo, Int X-HELO: rock.gnat.com Received: from rock.gnat.com (HELO rock.gnat.com) (205.232.38.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Tue, 25 Apr 2017 08:23:13 +0000 Received: from localhost (localhost.localdomain [127.0.0.1]) by filtered-rock.gnat.com (Postfix) with ESMTP id B109B29DCA; Tue, 25 Apr 2017 04:23:13 -0400 (EDT) Received: from rock.gnat.com ([127.0.0.1]) by localhost (rock.gnat.com [127.0.0.1]) (amavisd-new, port 10024) with LMTP id cw50XZVFWtVD; Tue, 25 Apr 2017 04:23:13 -0400 (EDT) Received: from tron.gnat.com (tron.gnat.com [IPv6:2620:20:4000:0:46a8:42ff:fe0e:e294]) by rock.gnat.com (Postfix) with ESMTP id 9BAA92970B; Tue, 25 Apr 2017 04:23:13 -0400 (EDT) Received: by tron.gnat.com (Postfix, from userid 4192) id 97A7C521; Tue, 25 Apr 2017 04:23:13 -0400 (EDT) Date: Tue, 25 Apr 2017 04:23:13 -0400 From: Arnaud Charlet To: gcc-patches@gcc.gnu.org Cc: Bob Duff Subject: [Ada] Latent bug in Uintp.Most_Sig_2_Digits Message-ID: <20170425082313.GA73746@adacore.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) This patch fixes a latent bug in Uintp.Most_Sig_2_Digits, that would cause a crash if Left is indirect and Right is direct. In fact, that combination never occurs in any existing calls. No test is available, because the bug is latent. Tested on x86_64-pc-linux-gnu, committed on trunk 2017-04-25 Bob Duff * uintp.adb (Most_Sig_2_Digits): In case Direct (Right), fetch Direct_Val (Right), instead of the incorrect Direct_Val (Left). (UI_GCD): Remove ??? comment involving possible efficiency improvements. This just isn't important after all these years. Also minor cleanup. * uintp.ads: Minor cleanup. Index: uintp.adb =================================================================== --- uintp.adb (revision 247135) +++ uintp.adb (working copy) @@ -52,7 +52,7 @@ UI_Power_2 : array (Int range 0 .. 64) of Uint; -- This table is used to memoize exponentiations by powers of 2. The Nth - -- entry, if set, contains the Uint value 2 ** N. Initially UI_Power_2_Set + -- entry, if set, contains the Uint value 2**N. Initially UI_Power_2_Set -- is zero and only the 0'th entry is set, the invariant being that all -- entries in the range 0 .. UI_Power_2_Set are initialized. @@ -149,9 +149,9 @@ Left_Hat : out Int; Right_Hat : out Int); -- Returns leading two significant digits from the given pair of Uint's. - -- Mathematically: returns Left / (Base ** K) and Right / (Base ** K) where + -- Mathematically: returns Left / (Base**K) and Right / (Base**K) where -- K is as small as possible S.T. Right_Hat < Base * Base. It is required - -- that Left > Right for the algorithm to work. + -- that Left >= Right for the algorithm to work. function N_Digits (Input : Uint) return Int; pragma Inline (N_Digits); @@ -264,7 +264,7 @@ ------------------- function Better_In_Hex return Boolean is - T16 : constant Uint := Uint_2 ** Int'(16); + T16 : constant Uint := Uint_2**Int'(16); A : Uint; begin @@ -506,6 +506,7 @@ pragma Assert (Left >= Right); if Direct (Left) then + pragma Assert (Direct (Right)); Left_Hat := Direct_Val (Left); Right_Hat := Direct_Val (Right); return; @@ -533,7 +534,7 @@ begin if Direct (Right) then - T := Direct_Val (Left); + T := Direct_Val (Right); R1 := abs (T / Base); R2 := T rem Base; Length_R := 2; @@ -1370,7 +1371,7 @@ elsif Right <= Uint_64 then - -- 2 ** N for N in 2 .. 64 + -- 2**N for N in 2 .. 64 if Left = Uint_2 then declare @@ -1390,7 +1391,7 @@ return UI_Power_2 (Right_Int); end; - -- 10 ** N for N in 2 .. 64 + -- 10**N for N in 2 .. 64 elsif Left = Uint_10 then declare @@ -1585,20 +1586,6 @@ else -- Use prior single precision steps to compute this Euclid step - -- For constructs such as: - -- sqrt_2: constant := 1.41421_35623_73095_04880_16887_24209_698; - -- sqrt_eps: constant long_float := long_float( 1.0 / sqrt_2) - -- ** long_float'machine_mantissa; - -- - -- we spend 80% of our time working on this step. Perhaps we need - -- a special case Int / Uint dot product to speed things up. ??? - - -- Alternatively we could increase the single precision iterations - -- to handle Uint's of some small size ( <5 digits?). Then we - -- would have more iterations on small Uint. On the code above, we - -- only get 5 (on average) single precision iterations per large - -- iteration. ??? - Tmp_UI := (UI_From_Int (A) * U) + (UI_From_Int (B) * V); V := (UI_From_Int (C) * U) + (UI_From_Int (D) * V); U := Tmp_UI; Index: uintp.ads =================================================================== --- uintp.ads (revision 247135) +++ uintp.ads (working copy) @@ -238,7 +238,7 @@ (B : Uint; E : Uint; Modulo : Uint) return Uint; - -- Efficiently compute (B ** E) rem Modulo + -- Efficiently compute (B**E) rem Modulo function UI_Modular_Inverse (N : Uint; Modulo : Uint) return Uint; -- Compute the multiplicative inverse of N in modular arithmetics with the @@ -438,7 +438,7 @@ Base_Bits : constant := 15; -- Number of bits in base value - Base : constant Int := 2 ** Base_Bits; + Base : constant Int := 2**Base_Bits; -- Values in the range -(Base-1) .. Max_Direct are encoded directly as -- Uint values by adding a bias value. The value of Max_Direct is chosen @@ -454,13 +454,13 @@ -- avoid accidental use of Uint arithmetic on these values, which is never -- correct. - type Ctrl is range Int'First .. Int'Last; + type Ctrl is new Int; Uint_Direct_Bias : constant Ctrl := Ctrl (Uint_Low_Bound) + Ctrl (Base); Uint_Direct_First : constant Ctrl := Uint_Direct_Bias + Ctrl (Min_Direct); Uint_Direct_Last : constant Ctrl := Uint_Direct_Bias + Ctrl (Max_Direct); - Uint_0 : constant Uint := Uint (Uint_Direct_Bias); + Uint_0 : constant Uint := Uint (Uint_Direct_Bias + 0); Uint_1 : constant Uint := Uint (Uint_Direct_Bias + 1); Uint_2 : constant Uint := Uint (Uint_Direct_Bias + 2); Uint_3 : constant Uint := Uint (Uint_Direct_Bias + 3); @@ -499,7 +499,7 @@ Uint_Minus_80 : constant Uint := Uint (Uint_Direct_Bias - 80); Uint_Minus_128 : constant Uint := Uint (Uint_Direct_Bias - 128); - Uint_Max_Simple_Mul : constant := Uint_Direct_Bias + 2 ** 15; + Uint_Max_Simple_Mul : constant := Uint_Direct_Bias + 2**15; -- If two values are directly represented and less than or equal to this -- value, then we know the product fits in a 32-bit integer. This allows -- UI_Mul to efficiently compute the product in this case.