[Bug ada/95452] New: Overflow Bug in GNAT Heapsort implementations

2020-05-31 Thread cthowie at netzero dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=95452

Bug ID: 95452
   Summary: Overflow Bug in GNAT Heapsort implementations
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: ada
  Assignee: unassigned at gcc dot gnu.org
  Reporter: cthowie at netzero dot net
  Target Milestone: ---

TOOLCHAINS: GCC GNAT FSF 8.2 and 10.1 (perhaps also 9.2 and others (?), I have
8.2 and 10.1).

ISSUE: All 3 "GNAT" implementations of Heapsort as found in the 'adainclude'
directory have an arithmetic overflow bug. The affected files are:

   g-heasor.adb
   g-hesorg.adb
   g-hesora.adb

REASON: in all 3 implementations, the nested subprogram called "Sift", inside
the procedure "Sort", uses the following expression:

   Son := 2 * C;

where "Son" and "C" are type "Positive". Note that in "g-heasor.adb" the
expression is a variant with the same overflow problem:

   Son := C + C;

Clearly, any integer type when doubled can overflow unless steps are taken to
mitigate e.g., by doubling "C" using a wider type like a Long_Long_Integer and
then comparing that with the surrounding loop termination condition (note that
"Max", like "Son", is type Positive in the affected code):

   exit when Son > Max;

In the current implementations, there is no check for this overflow, meaning
Heapsort fails with a runtime exception under certain inputs, when it need not.
The sort works if you trap the overflow and exit the loop. Thus the current
implementation is broken for any arrays of length greater than Positive'Last /
2.

EXAMPLE SOLUTION
A solution could therefore be to change the loop body of "Sift" to something
like the following:

   loop
  declare
 Two_C : constant Long_Long_Integer := 2 * Long_Long_Integer (C);

 pragma Suppress (All_Checks);  
 --  It'll be safe to convert Two_C to Son if we get past 
 --  the 'exit' check i.e., to take the lower precision integer 
 --  value (here 32 bits from 64 bits)
  begin
 exit when Two_C > Long_Long_Integer (Max);
 Son := Positive (Two_C);
  end;

  if Son < Max then
 if Lt (Son, Son + 1) then
Son := Son + 1;
 end if;
  end if;

  Move (Son, C);
  C := Son;
   end loop;

Note that the three files cited don't have identical code with respect to
checking for loop termination, but they have the same logical meaning i.e., in
my 10.1 toolchains, "g-hesorg.adb" and "g-heasor.adb" use:

   Son := 2 * C;
   if Son < Max then
  if Lt (Son, Son + 1) then
 Son := Son + 1;
  end if;
   elsif Son > Max then --  termination is checked down here

while "g-hesora.adb" uses the form I demonstrated in the above solution:

   loop
  Son := 2 * C;
  exit when Son > Max;  --  termination is checked early
  if Son < Max and then Lt (Son, Son + 1) then
 Son := Son + 1;
  end if;

[Bug ada/92362] New: Compiler generates 2 function calls in a 'with Address' aspect specification that uses a function

2019-11-04 Thread cthowie at netzero dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=92362

Bug ID: 92362
   Summary: Compiler generates 2 function calls in a 'with
Address' aspect specification that uses a function
   Product: gcc
   Version: 9.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: ada
  Assignee: unassigned at gcc dot gnu.org
  Reporter: cthowie at netzero dot net
  Target Milestone: ---

PLATFORM USED: GCC 9.2 toolchain on Windows 10 Intel x64 using MSYS2 (mingw64).
Note the GNAT FSF 8.2 compiler does NOT have the bug.

ISSUE: Multiple calls to a function that returns an address for use "with
Address".
Note that if you use the alternative (non-aspect) attribute definition clause,
the bug doesn't appear in 9.2, so a statement like:
   bar : Integer;
   for bar'Address use Get_Address;
is handled properly but:
   bar : Integer with Address => Get_Address;
is compiled defectively.

EXAMPLE PROGRAM DEMONSTRATING THE BUG:
  with Ada.Text_IO; use Ada.Text_IO;
  with System;

  procedure Main
  is
 foo : Integer := 0;

 function Get_Address return System.Address
 is
 begin
Put_Line ("Get_Address called");
return foo'Address;
 end Get_Address;

 bar : Integer with Address => Get_Address;  -- Get_Address called
TWICE = BUG!
  begin
 bar := 100;
 Put_Line ("foo = " & foo'Img);
  end Main;

BUILD INSTRUCTIONS:
Save the above example program to e.g., "main.adb" then run: gnatmake main.adb
then run the program "main.exe" and you'll see GCC GNAT FSF 9.2 output is
incorrect:
  Get_Address called
  Get_Address called
  foo =  100
whereas earlier version GNAT FSF 8.2 produces correct output:
  Get_Address called
  foo =  100
and so does current GNAT FSF 9.2 but only if you use the more verbose attribute
definition clause shown above.

[Bug ada/87973] New: ICE with pragma Discard_Names and GCC optimisation for x64

2018-11-11 Thread cthowie at netzero dot net
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87973

Bug ID: 87973
   Summary: ICE with pragma Discard_Names and GCC optimisation for
x64
   Product: gcc
   Version: 8.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: ada
  Assignee: unassigned at gcc dot gnu.org
  Reporter: cthowie at netzero dot net
  Target Milestone: ---

Created attachment 44985
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=44985&action=edit
Test.adb file; see comment for other file 'Test.gpr'

PREFACE: 
1) Compiler: GNAT FSF 8.2.0 with MinGW on Windows 64-bit. I've appended the
detailed output of "gcc -v" to the end of this comment.

2) My GNAT setup is default MSYS2 based GNAT FSF on Windows 64/MinGW64. No
fiddling or manual compiling of GNAT. I have also installed the Win32Ada
library from GitHub, though there are problems even if Win32Ada ignored as I
comment on below.

3) The compiler crash and other problems reported herein do not appear to
affect x86 (32-bit) GNAT, only x64. I ran these steps below on 32-bit Windows
with MSYS2 GNAT x86 and had no problems.

TWO TEST FILES: Test.adb, Test.gpr
Although I've attached Test.adb, you can make these two files by pasting the
following text into the named files (gnatchop won't work):
 Test.adb  
with Ada.Text_IO; use Ada.Text_IO;
procedure Test
is
pragma Discard_Names;
type Name is (Alice, Bob, Charles);
n : Name := Bob;
begin
Put_Line ("Hello, " & n'Image);
end Test;
 Test.gpr  
with "win32ada";
project Test is
for Source_Dirs use (".");
for Object_Dir use "obj/";
for Main use ("Test.adb");
package Compiler is
for Switches ("Ada") use ("-O2");
end Compiler;
end Test;
 end of test files -- 

DIAGNOSTIC STEPS:
I will describe how to generate the ICE and then some finer-grained diagnostic
steps you can use to remove the ICE but get a compiler error which I'm sure
will help home in on the bug, and then finally how to get the pragma working
even with optimisation switched on.

To generate the ICE, run 'gprbuild' for the simple test and project files I've
submitted:

   gprbuild -p -d -PTest.gpr

and you get this bug box   
+===GNAT BUG
DETECTED==+
| 8.2.0 (x86_64-w64-mingw32) Program_Error EXCEPTION_ACCESS_VIOLATION  
   |
| Error detected at test.adb:8:32  
   |
| Please submit a bug report; see https://gcc.gnu.org/bugs/ .  
   |
| Use a subject line meaningful to you and us to track the bug.
   |
| Include the entire contents of this bug box in the report.   
   |
| Include the exact command that you entered.  
   |
| Also include sources listed below.   
   |
   
+==+

The crash relates to a combination of things:
 - specifying Win32Ada in the project file
 - the use of pragma Discard_Names inside a procedure (not at file scope)
 - the use of GCC optimisation
Yet there seems to be a non-crashing bug if we drop the Win32Ada aspect because
the compiler will produce an incorrect message unless we drop optimisation as
well. To explore this further, proceed through the following steps:

1) In the Test.gpr file, comment out or remove the first line that says "with
win32ada;" as this will prevent the compiler from crashing but will give us a
new clue by triggering an incorrect compiler error message. Note that the
Win32Ada library is not actually used in this test, it's just here because I've
stripped down the test files from a bigger project and Win32Ada may help in
diagnosing the problem. Even if you don't have the Win32Ada library installed,
you can still get problems when combining the pragma with optimisation, but the
ICE itself is related to the Win32Ada specification. So, after commenting
out/removing that "with win32ada;" line and running the same command:

   gprbuild -p -d -PTest.gpr

you'll see the bug box has gone but now there's an incorrect compiler error
message (incorrect because the program is legal), and the error message itself
is suspicious in claiming an empty string is undefined:

   test.adb:8:32: "" is undefined

2) Now in the Test.gpr file, comment out (or remove) the line that sets the Ada
compiler switches. The issue appears related to the use of optimisation
(whether GCC level -O1 or -O2, there's a bug somewhere). Running the same
command as before:
   gprbuild -p -d -PTest.gpr
gives a

[Bug ada/104703] New: GNAT 11.2 exception traceback output is mostly garbled on Intel x64 (MSYS2)

2022-02-26 Thread cthowie at netzero dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=104703

Bug ID: 104703
   Summary: GNAT 11.2 exception traceback output is mostly garbled
on Intel x64 (MSYS2)
   Product: gcc
   Version: 11.2.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: ada
  Assignee: unassigned at gcc dot gnu.org
  Reporter: cthowie at netzero dot net
  Target Milestone: ---

PLATFORM: GCC 11.2 Revision 8 toolchain for MSYS2 on Windows 10 Intel x64 CPU.
Note GNAT FSF 8.2 Revision 1 compiler does NOT have the problem as shown below.

ISSUE: I upgraded from GNAT FSF 8.2 to GNAT FSF 11.2 and noticed the
"traceback" output is now garbled as demonstrated below with a trivial Ada
program:

EXAMPLE PROGRAM DEMONSTRATING THE ISSUE:

   procedure Main
   is
  procedure Inner with No_Inline is
  begin
 raise Program_Error;
  end Inner;
   begin
  Inner;
   end Main;

BUILD INSTRUCTIONS:
Save the above example program to e.g., "main.adb" then run:

   gnatmake -g main.adb -bargs -Es

so we get symbolic traceback for the raised exception. Then run the 'main.exe'
from the command line. I get this broken trace (only the bottom 4 lines for
KERNEL32.DLL and ntdll.dll are correct):

$ ./main

   raised PROGRAM_ERROR : main.adb:8 explicit raise
   [C:\temp\GNAT bug\main.exe]
   0x7ff6ecbe1a1e ??? at ???
   [C:\temp\GNAT bug\main.exe]
   0x7ff6ecbe1a41 ??? at ???
   [C:\temp\GNAT bug\main.exe]
   0x7ff6ecbe1992 ??? at ???
   [C:\temp\GNAT bug\main.exe]
   0x7ff6ecbe13af ??? at ???
   [C:\temp\GNAT bug\main.exe]
   0x7ff6ecbe14e4 ??? at ???
   [C:\windows\System32\KERNEL32.DLL]
   0x7ffb5c5f81f2
   [C:\windows\SYSTEM32\ntdll.dll]
   0x7ffb5f05a24f

The trace is broken even:
1) if I bind with the "-Ea" binder flag
2) if I use the GNAT system package and Text_IO e.g.,
  with GNAT.Traceback.Symbolic; use GNAT.Traceback.Symbolic;
   and add this to the bottom of the main subprogram:
  exception
 when e : others => Put_Line (Symbolic_Traceback (e));

Note that the traceback is correct if I compile exactly as above but with GNAT
FSF 8.2 Revision 1 compiler for MSYS2:

   raised PROGRAM_ERROR : main.adb:8 explicit raise
   [C:\temp\GNAT bug\main.exe]
   Main.Inner at main.adb:8
   Main at main.adb:12
   Main at b~main.adb:188
   __tmainCRTStartup at crtexe.c:333
   mainCRTStartup at crtexe.c:217
   [C:\windows\System32\KERNEL32.DLL]
   0x7ffb5c5f81f2
   [C:\windows\SYSTEM32\ntdll.dll]
   0x7ffb5f05a24f

[Bug ada/106318] New: ICE when using 'Range in Ada22 Iterated Component Association

2022-07-15 Thread cthowie at netzero dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106318

Bug ID: 106318
   Summary: ICE when using 'Range in Ada22 Iterated Component
Association
   Product: gcc
   Version: 12.1.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: ada
  Assignee: unassigned at gcc dot gnu.org
  Reporter: cthowie at netzero dot net
  Target Milestone: ---

PLATFORM: GCC 12.1.0 toolchain on Windows 10 Intel x64 using MSYS2 (Mingw64).

ISSUE: the use of 'Range sometimes causes an internal compiler error (ICE) when 
used in an Iterated Component Association per Ada 2022 syntax. Note that in the
example program below that illustrates the bug, I had to use a nested
subprogram, otherwise 'Range seemed to work OK in the Main subprogram itself:

In short, this syntax works:

   new Local_Array'(for I in Arr'First .. Arr'Last =>

but this syntax crashes GNAT:

   new Local_Array'(for I in Arr'Range =>

It seems a temporary workaround for the bug is to replace use of 'Range with
'First .. 'Last in cases where GNAT crashes ('Range isn't universally broken).


EXAMPLE PROGRAM DEMONSTRATING THE BUG
=

--  COMPILE WITH: gnatmake main.adb -gnat2022
--  The code as it stands triggers an ICE as indicated in the comment below.
--  The culprit is the "for I in Arr'Range" being used in the Iterated 
--  Component Association syntax of Ada 2022.
--  If you comment out the line that "FAILS!", and uncomment the line that
"WORKS",
--  then you'll get stable code using Arr'First .. Arr'Last.

with Ada.Text_IO; use Ada.Text_IO;
with Ada.Unchecked_Deallocation;

procedure Main
is
   type Int_Array is array (Positive range <>) of Integer;
   type Int_Array_Acc is access Int_Array;
   procedure Free is new Ada.Unchecked_Deallocation (Int_Array, Int_Array_Acc);

   Foo : constant Int_Array := [1, 2, 3];

   procedure Nested --  replaces Arr with a similar one
  (Arr : in out Int_Array_Acc)
   is
  --  +===GNAT BUG ETECTED =
  --  | 12.1.0 (x86_64-w64-mingw32) GCC error:
  --  | in gnat_to_gnu_entity, at ada/gcc-interface/decl.cc:472

  Replace : constant Int_Array_Acc :=
--new Int_Array'(for I in Arr'First .. Arr'Last =>   --  THIS WORKS
new Int_Array'(for I in Arr'Range => --  THIS FAILS!
   (if Arr (I) = 2
then 0
else Arr (I)));
   begin
  Free (Arr);
  Arr := Replace;
   end Nested;

   Goo : Int_Array_Acc := new Int_Array'(Foo);
begin
   Put_Line ("Goo =" & Goo.all'Image);  --  should print [ 1,  2,  3]
   Nested (Goo);
   Put_Line ("Goo =" & Goo.all'Image);  --  should print [ 1,  0,  3]
   Free (Goo);
end Main;

[Bug ada/116089] New: GNATprove raises Program_Error for loop frame condition when calling function with Side_Effects

2024-07-25 Thread cthowie at netzero dot net via Gcc-bugs
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116089

Bug ID: 116089
   Summary: GNATprove raises Program_Error for loop frame
condition when calling function with Side_Effects
   Product: gcc
   Version: unknown
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: ada
  Assignee: unassigned at gcc dot gnu.org
  Reporter: cthowie at netzero dot net
CC: dkm at gcc dot gnu.org
  Target Milestone: ---

PLATFORM: GCC 14.1 toolchain on Windows 10 Intel x64 using MSYS2 (mingw64).
  GNATprove FSF 14.1

ISSUE: Putting a conditional function with Side_Effects in a simple loop
triggers Program_Error from GNATprove

TRIVIAL SUBPROGRAM DEMONSTRATING THE BUG:

  procedure Demo_Bug
  with SPARK_Mode
  is
 type Buffer is array (1 .. 10) of Integer;

 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

 function Test
   (B : Buffer;
Idx   : Positive;
Found : out Positive)   --  force the use of Side_Effects
   return Boolean
 with No_Inline,
   Side_Effects,
   Always_Terminates,
   Pre => Idx in B'Range
 is
 begin
if B (Idx) > 0 then
   Found := Idx;
   return True;
end if;
Found := B'Last + 1;
return False;
 end Test;

 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

 Value  : Positive;
 A  : Buffer := (others => 0);
 Idx: Positive;
 Result : Boolean;
  begin
 for Idx in A'Range loop
Result := Test (A, Idx, Value);
if not Result then
   exit;   --  RAISES Program_Error
end if;
 end loop;
  end Demo_Bug;


BUILD INSTRUCTIONS:
Save the above example program to e.g., "demo_bug.adb" then run:

   gnatprove demo_bug.adb

I got this output:

$ gnatprove demo_bug.adb
No project file given, using default.gpr
Phase 1 of 3: generation of data representation information ...
Phase 2 of 3: generation of Global contracts ...
Phase 3 of 3: flow analysis and proof ...
error in computation of loop frame condition for demo_bug__value
+===GNAT BUG DETECTED==+
| 1.0 (spark) Program_Error gnat2why-expr-loops-inv.adb:1052 explicit raise|
| Error detected at demo_bug.adb:37:10 |
| Compiling C:\temp\GNATprove_Bug\demo_bug.adb |
| Please submit a bug report; see https://gcc.gnu.org/bugs/ .  |
| Use a subject line meaningful to you and us to track the bug.|
| Include the entire contents of this bug box in the report.   |
| Include the exact command that you entered.  |
| Also include sources listed below.   |
+==+