From 5ce1c7733b720d583eb46910e738adc932ecf7ce Mon Sep 17 00:00:00 2001 From: Bob Duff Date: Wed, 18 Sep 2019 08:31:37 +0000 Subject: [PATCH] [Ada] Avoid uninitialized variable in bounded containers In function Copy in Ada.Containers.Bounded_Ordered_Sets and other bounded containers packages, remove a possible use of an uninitialized variable. This was not a bug, because the uninitialized variable could be used only if checks are suppressed, and the checks would have failed, leading to erroneous execution. However, it seems more robust this way, and is probably equally efficient, and avoids a warning that is given if checks are suppressed, and the -Wall switch is given, and optimization is turned on. 2019-09-18 Bob Duff gcc/ada/ * libgnat/a-cbhama.adb, libgnat/a-cbhase.adb, libgnat/a-cbmutr.adb, libgnat/a-cborma.adb, libgnat/a-cborse.adb, libgnat/a-cobove.adb (Copy): Avoid reading the uninitialized variable C in the Checks = False case. Change variable to be a constant. gcc/testsuite/ * gnat.dg/containers1.adb, gnat.dg/containers1.ads: New testcase. From-SVN: r275839 --- gcc/ada/ChangeLog | 8 ++++++++ gcc/ada/libgnat/a-cbhama.adb | 14 +++++--------- gcc/ada/libgnat/a-cbhase.adb | 12 +++++------- gcc/ada/libgnat/a-cbmutr.adb | 13 +++++-------- gcc/ada/libgnat/a-cborma.adb | 15 +++++---------- gcc/ada/libgnat/a-cborse.adb | 13 +++++-------- gcc/ada/libgnat/a-cobove.adb | 16 +++++----------- gcc/testsuite/ChangeLog | 5 +++++ gcc/testsuite/gnat.dg/containers1.adb | 5 +++++ gcc/testsuite/gnat.dg/containers1.ads | 6 ++++++ 10 files changed, 54 insertions(+), 53 deletions(-) create mode 100644 gcc/testsuite/gnat.dg/containers1.adb create mode 100644 gcc/testsuite/gnat.dg/containers1.ads diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 8906ea1b537..d4c51d102d7 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,3 +1,11 @@ +2019-09-18 Bob Duff + + * libgnat/a-cbhama.adb, libgnat/a-cbhase.adb, + libgnat/a-cbmutr.adb, libgnat/a-cborma.adb, + libgnat/a-cborse.adb, libgnat/a-cobove.adb (Copy): Avoid reading + the uninitialized variable C in the Checks = False case. Change + variable to be a constant. + 2019-09-18 Claire Dross * libgnat/a-cofuma.adb (Remove, Elements_Equal_Except, diff --git a/gcc/ada/libgnat/a-cbhama.adb b/gcc/ada/libgnat/a-cbhama.adb index 68e3602d879..74e3d95748a 100644 --- a/gcc/ada/libgnat/a-cbhama.adb +++ b/gcc/ada/libgnat/a-cbhama.adb @@ -262,18 +262,14 @@ package body Ada.Containers.Bounded_Hashed_Maps is Capacity : Count_Type := 0; Modulus : Hash_Type := 0) return Map is - C : Count_Type; + C : constant Count_Type := + (if Capacity = 0 then Source.Length + else Capacity); M : Hash_Type; begin - if Capacity = 0 then - C := Source.Length; - - elsif Capacity >= Source.Length then - C := Capacity; - - elsif Checks then - raise Capacity_Error with "Capacity value too small"; + if Checks and then C < Source.Length then + raise Capacity_Error with "Capacity too small"; end if; if Modulus = 0 then diff --git a/gcc/ada/libgnat/a-cbhase.adb b/gcc/ada/libgnat/a-cbhase.adb index 796cb971421..390e82bb485 100644 --- a/gcc/ada/libgnat/a-cbhase.adb +++ b/gcc/ada/libgnat/a-cbhase.adb @@ -254,16 +254,14 @@ package body Ada.Containers.Bounded_Hashed_Sets is Capacity : Count_Type := 0; Modulus : Hash_Type := 0) return Set is - C : Count_Type; + C : constant Count_Type := + (if Capacity = 0 then Source.Length + else Capacity); M : Hash_Type; begin - if Capacity = 0 then - C := Source.Length; - elsif Capacity >= Source.Length then - C := Capacity; - elsif Checks then - raise Capacity_Error with "Capacity value too small"; + if Checks and then C < Source.Length then + raise Capacity_Error with "Capacity too small"; end if; if Modulus = 0 then diff --git a/gcc/ada/libgnat/a-cbmutr.adb b/gcc/ada/libgnat/a-cbmutr.adb index fb8585a100f..4c0f8fe1c29 100644 --- a/gcc/ada/libgnat/a-cbmutr.adb +++ b/gcc/ada/libgnat/a-cbmutr.adb @@ -625,15 +625,12 @@ package body Ada.Containers.Bounded_Multiway_Trees is (Source : Tree; Capacity : Count_Type := 0) return Tree is - C : Count_Type; - + C : constant Count_Type := + (if Capacity = 0 then Source.Count + else Capacity); begin - if Capacity = 0 then - C := Source.Count; - elsif Capacity >= Source.Count then - C := Capacity; - elsif Checks then - raise Capacity_Error with "Capacity value too small"; + if Checks and then C < Source.Count then + raise Capacity_Error with "Capacity too small"; end if; return Target : Tree (Capacity => C) do diff --git a/gcc/ada/libgnat/a-cborma.adb b/gcc/ada/libgnat/a-cborma.adb index 55be7ad0327..e4e4b57dc72 100644 --- a/gcc/ada/libgnat/a-cborma.adb +++ b/gcc/ada/libgnat/a-cborma.adb @@ -464,17 +464,12 @@ package body Ada.Containers.Bounded_Ordered_Maps is ---------- function Copy (Source : Map; Capacity : Count_Type := 0) return Map is - C : Count_Type; - + C : constant Count_Type := + (if Capacity = 0 then Source.Length + else Capacity); begin - if Capacity = 0 then - C := Source.Length; - - elsif Capacity >= Source.Length then - C := Capacity; - - elsif Checks then - raise Capacity_Error with "Capacity value too small"; + if Checks and then C < Source.Length then + raise Capacity_Error with "Capacity too small"; end if; return Target : Map (Capacity => C) do diff --git a/gcc/ada/libgnat/a-cborse.adb b/gcc/ada/libgnat/a-cborse.adb index 9fdba269d28..7b983781e60 100644 --- a/gcc/ada/libgnat/a-cborse.adb +++ b/gcc/ada/libgnat/a-cborse.adb @@ -442,15 +442,12 @@ package body Ada.Containers.Bounded_Ordered_Sets is ---------- function Copy (Source : Set; Capacity : Count_Type := 0) return Set is - C : Count_Type; - + C : constant Count_Type := + (if Capacity = 0 then Source.Length + else Capacity); begin - if Capacity = 0 then - C := Source.Length; - elsif Capacity >= Source.Length then - C := Capacity; - elsif Checks then - raise Capacity_Error with "Capacity value too small"; + if Checks and then C < Source.Length then + raise Capacity_Error with "Capacity too small"; end if; return Target : Set (Capacity => C) do diff --git a/gcc/ada/libgnat/a-cobove.adb b/gcc/ada/libgnat/a-cobove.adb index 8d80fb70323..3e48bc60e8a 100644 --- a/gcc/ada/libgnat/a-cobove.adb +++ b/gcc/ada/libgnat/a-cobove.adb @@ -451,18 +451,12 @@ package body Ada.Containers.Bounded_Vectors is (Source : Vector; Capacity : Count_Type := 0) return Vector is - C : Count_Type; - + C : constant Count_Type := + (if Capacity = 0 then Source.Length + else Capacity); begin - if Capacity = 0 then - C := Source.Length; - - elsif Capacity >= Source.Length then - C := Capacity; - - elsif Checks then - raise Capacity_Error - with "Requested capacity is less than Source length"; + if Checks and then C < Source.Length then + raise Capacity_Error with "Capacity too small"; end if; return Target : Vector (C) do diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index cc27ca318c2..5e143b57456 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2019-09-18 Bob Duff + + * gnat.dg/containers1.adb, gnat.dg/containers1.ads: New + testcase. + 2019-09-18 Richard Sandiford * gcc.target/i386/pr82361-1.c (f1, f2, f3, f4, f5, f6): Force diff --git a/gcc/testsuite/gnat.dg/containers1.adb b/gcc/testsuite/gnat.dg/containers1.adb new file mode 100644 index 00000000000..47ac655e21b --- /dev/null +++ b/gcc/testsuite/gnat.dg/containers1.adb @@ -0,0 +1,5 @@ +-- { dg-do compile } +-- { dg-options "-Wall -O2" } +package body Containers1 is + procedure Dummy is null; +end Containers1; diff --git a/gcc/testsuite/gnat.dg/containers1.ads b/gcc/testsuite/gnat.dg/containers1.ads new file mode 100644 index 00000000000..3c1fd89b228 --- /dev/null +++ b/gcc/testsuite/gnat.dg/containers1.ads @@ -0,0 +1,6 @@ +with Ada.Containers.Bounded_Ordered_Sets; use Ada.Containers; +package Containers1 is + pragma Suppress (All_Checks); + package Sets is new Bounded_Ordered_Sets (Boolean); + procedure Dummy; +end Containers1; \ No newline at end of file -- 2.30.2