[Bug ada/95452] New: Overflow Bug in GNAT Heapsort implementations
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
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
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)
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
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
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. | +==+