❌ About FreshRSS

Normal view

There are new articles available, click to refresh the page.
Yesterday — 29 November 2023News from the Ada programming language world

Elaboration circularity detected

By: jackpg
29 November 2023 at 15:19

Hi, I am new in this forum.
I have a problem porting ada code from Red Hat 8 (gnat 8.5.0) to Red Hat 9 (gnat 11.3.1).
The linking phase on RHEL9 fails for “Elaboration circularity detected”.
I let the ada compiler to choose the module compilation order using the following instruction:
gnatmake -c
The reason is: “unit depends on its own elaboration”
The circularity detected is: "unit invokes a construct of unit at elaboration time.
What shall I do to find the exact location of the problem?
And why this problem was not detected before using other gnat versions?
Thanks a lot

6 posts - 3 participants

Read full topic

Possible compiler bug?

By: jere
29 November 2023 at 14:14

I have some code that is running fine for me at home using gnat/gcc 12.2. I decided to test it out on various versions of gnat, so I fired up godbolt and tried a few. I found that starting with version 13, my code throws an exception when the program ends:

raised PROGRAM_ERROR : example.adb:4 finalize/adjust raised exception

I wanted to double check and make sure I am not doing anything illegal and 13 catches it vs 13 just having a bug. I had to make a kinda convoluted example since the original code was from a much larger code base, so apologies if the generic formals and code don’t look too practical. I spent a few hours whittling it down from the original. Full code on godbolt is here:

Code is below:


with Ada.Text_IO; use Ada.Text_IO;
with Test;

procedure Example is

    package B is 
        type Instance is limited interface;
        function Make return Instance is abstract;
    end B;

    package C is
        type Instance is new B.Instance with null record;
        function Make return Instance is (null record);
    end C; use C;

    package T is new Test(B.Instance, C.Instance, C.Make);

    Thing : B.Instance'Class := T.Make(2);

    Put_Line("Hello World");
end Example;


    type First(<>) is abstract tagged limited private;
    type Second(<>) is new First with private;
    with function Make return Second is <>;
package Test is

    function Make(Key : Integer) return First'Class;


    type Some_Access is not null access function return First'Class;

    function Make_Delegate return First'Class;

    Thing_Access : constant Some_Access := Make_Delegate'Access;

end Test;


with Ada.Containers.Indefinite_Ordered_Maps;

package body Test is

    package Maps is new Ada.Containers.Indefinite_Ordered_Maps
        (Key_Type     => Integer,
         Element_Type => Some_Access);

    Map : Maps.Map;

    function Make(Key : Integer) return First'Class is
        return Map(Key).all;
    end Make;

    function Make_Delegate return First'Class is
        return Make;
    end Make_Delegate;

end Test;

It’s essentially a map of function pointers (only one in this example). I had to use a wrapper function (Make_Delegate) in order to have correct accessibility to it within the generic.

7 posts - 3 participants

Read full topic

Before yesterdayNews from the Ada programming language world

Gnatd.v elaboration

By: kevlar700
22 November 2023 at 15:11

I wonder. Is gnatd.v a better option than
pragma preelaborate

Is preelaborate more compiler portable? Though I do not use the features that it protects against such as dynamic dispatch, so it is simply an unneeded restriction for me with Gnat. However gnatd.v seems to offer more such as in regard to uninitialised variables? Assuming it works as I had no compile issues :joy:.

see 7.7


2 posts - 2 participants

Read full topic

Regarding END_ERROR when using Ada.Text_IO.Set_Line on IN_FILE

By: Reed
21 November 2023 at 11:17

When using the procedure Set_Line (File, X) after using the procedure Skip_Line(File, Y) the error, END.ERROR is raised when X <= Y
(except when X = Y = 1).

When the procedure Set_Line (File, X) is called on a File of mode IN_FILE, it internally calls Skip_Line until the file line number reaches X.
If X is not equal than the current line in the file, the procedure will continuously skip lines until it reaches another page with a matching line. (RM 2022 p.g.523)

I am curious about the reasoning for this functionality as it has caused an amusing problem in the trivial program I am writing.
The program will get the number of lines from a .txt file and select a random line to print to the console. A word of the day program.
Minimal Example of Issue:

with Ada.Text_IO; use Ada.Text_IO;

procedure Main is

   File_Name : constant String := "TEST.txt";
   Test_File : File_Type;

   Create (Test_File, Out_File, File_Name);

   for I in 1 .. 10 loop
      Put_Line (Test_File, "Line :" & Integer'Image (I));
   end loop;

   Close (Test_File);
   Open (Test_File, In_File, "Test.txt");

   Skip_Line (Test_File, 5);

   Set_Line (Test_File, 4);

end Main;
--Will raise End_Error

I would think that the procedure would check if X < File.Line then perform further actions. While am able to work around this, I am interested to understand the reasoning.

9 posts - 5 participants

Read full topic

Using Long_Float in inline assembler for ARM

By: AhlanM
19 November 2023 at 12:33

Using GNAT v11.2/0-4 for ARM (Alire), the following procedure Unbiased_Rounding for Float works as expected.

function Unbiased_Rounding (X : Float) return Float is
Y : Float;
Asm (“vrintn.f32 %0,%1”,
Outputs => Float’asm_output (“=t”, Y),
Inputs => Float’asm_input (“t”, X));
return Y;
end Unbiased_Rounding;

according to Machine Constraints (Using the GNU Compiler Collection (GCC))
the constraint t means "VFP floating-point registers s0-s31. Used for 32 bit values” and the constraint w means "VFP floating-point registers d0-d31 and the appropriate subset d0-d15 based on command line options. Used for 64 bit values only”

therefore we wrote our long_float version as

function Unbiased_Rounding (X : Long_Float) return Long_Float is
Y : Long_Float;
Asm (“vrintn.f64 %0,%1”,
Outputs => Long_Float’asm_output (“=w”, Y),
Inputs => Long_Float’asm_input (“w”, X));
return Y;
end Unbiased_Rounding;

however this fails to compile.
GNAT 11.2/0-4 (Alire) complains
Error: invalid instruction shape – `vrintn.f64 s14,s14’

presumably because the operands are S registers rather than double precisions D registers.
Is this a bug or have we misunderstood something?

Best wishes,

8 posts - 4 participants

Read full topic

Gnatprove detailed counterexample trace outside GNAT Studio?

18 November 2023 at 02:46

When gnatprove is used with “–counterexamples=on” inside GNAT Studio it is able to present a detailed trace[1]:


This nice trace only seems to work inside GNAT Studio, not inside the VSCode AdaCore.ada plugin. Is there a way to output this trace to a text console (e.g. by passing an option to the gnatprove command-line command) so that this trace feature can be used outside GNAT Studio?

[1] 7.2. How to View GNATprove Output — SPARK User's Guide 25.0w

2 posts - 2 participants

Read full topic

Understanding `select or delay until` in tasks

By: cunger
17 November 2023 at 06:29

I’m playing with tasks and have a question about select with delay until.

I have a task with the following body (the full implementation is on GitHub):

Wait : loop
      -- Wait for pings. When they come, reset Last_Ping.
      accept Ping do
          Log.Debug ("Received ping.");
          Last_Ping := Clock;
      end Ping;
      -- If there is no ping within the expected interval, do something.
      delay until (Last_Ping + Expected_Ping_Interval);
      Log.Error ("Timeout!");
      -- Do something.
      -- Is there any way to keep running the task loop here? 
   end select;
end loop Wait;

From how I understand the select, it waits for the specified delay - if there is a Ping before the end of the delay, the loop iteration is finished and the next iteration is started, again waiting for the specified delay or accepting a Ping.

Now, when the delay is over and there was no entry in Ping, it does not proceed with the next loop iteration but is finished, right? Why is that? And is there a way to write this loop so the task continues running?

(Also happily take pointers to good resources for learning about task behavior in more depth. :slight_smile:)

6 posts - 3 participants

Read full topic

Spark with a private global log store

By: kevlar700
7 November 2023 at 18:21

I have a log package with a private global variable that passes silver mode except for a couple of low upper bound string issues. It has a fixed sized global variable as the log store.

However any external procedure running in spark mode that tries to execute a log function is wanted by spark to have the state or log store listed in it’s global aspect even though it has no access to the private log store directly.

I assume that I am missing something and shall keep reading but any help would be much appreciated? It isn’t workable for me to create global aspects for any procedure that uses my log package. I guess I could pass the log store but I am not sure that that is a good solution.


3 posts - 2 participants

Read full topic

Gnu Emacs ada-mode - passing the torch

4 November 2023 at 21:47

8.1.0 is my last release as Emacs ada-mode maintainer; it’s time for
me to retire.

I’m not using Ada for any serious projects (other than ada-mode
itself), my health is declining, and all my available energy is taken
by my darling baby grandaughter (FIXME: attach photo).

So I’m looking for someone to take over as maintainer. Ideally, this
would be someone employed by a company that values Ada and Emacs, but
anyone with sufficient interest, energy, and time can do the job.

I’ll be available to teach the new maintainer what they need to know.

If you are interested, contact me via the Emacs ada-mode mailing list
(Emacs Ada mode - Mailing Lists [Savannah]) or directly at
[email protected].

What’s involved in being ada-mode maintainer?

  • Wisitoken parser generator and runtime

    • All Ada (very small amount of C in the lexer wrapper)
      • 92 files, 18k statements
    • uses re2c lexer generator (generates C code)
    • generalized LR, error-correction, incremental
    • very complex Ada code
    • User grammar source file is parsed by a WisiToken parser
    • full test suite
      • 52 Ada files, 3492 statements
      • 45 grammar files
    • some documentation of algorithms
  • gnat-compiler package

    • elisp wrapper to call gnat tools in various ways
    • 3 elisp files, 1938 lines
  • gpr-query package

    • Provides project-wide cross reference for Ada
    • mix of elisp and Ada
      • 1 Ada file 211 statements, 1 elisp file 1075 lines
    • The Ada code is evolved from an old AdaCore utility
    • it uses gnatcoll packages to query a database built from .ali
      files produced by the GNAT compiler.
  • wisi indentation, face, navigation package

    • mix of Emacs lisp and Ada
      • 19 Ada files, 2592 statements
      • 8 elisp files, 7097 lines
    • interfaces to wisitoken parser in a separate process
    • Uses rules in the grammar, and the syntax tree produced by parser,
      to compute indentation, face, navigation.
    • tested by the ada-mode test suite
  • ada-mode package

    • Uses wisi, gnat-compiler
    • uses gpr-query or ada_language_server via eglot for cross-reference.
    • some Ada code to customize wisi computations
      • 15 Ada files generated by wisitoken
      • 15 Ada files, 2361 statements
      • 7 elisp files 4102 lines
    • ada_annex_p.wy grammar file derived from ARM Annex P. (3037 lines)
    • also supports ada_language server via eglot
  • gpr-mode package

    • for GNAT .gpr files
    • uses wisi, gnat-compiler
    • small amount of Ada code to customize wisi computations
    • gpr.wy grammar file derived from gprbuild user guide.
  • wisitoken-grammar-mode

    • for .wy files
    • uses wisi
    • grammar file derived from that used to generate WisiToken grammar
      source file parser
  • ada-ref-man package

    • Provides info version of Ada Reference Manual as an ELPA package
    • Has Ada code that adds info capability to the official ARM formatting program

There could be one maintainer for all of the above, or several to
share the work as they see fit.

I’ve had a lot of fun maintaining ada-mode over the years (I’ve lost
track of when I started; sometime around 1995?). While I was working
at NASA writing Ada for dynamic simulators, it was very nice to be
able to just fix ada-mode to do what I wanted. Adding error correction
and incremental parsing to the parser was very challenging, and very
satisfying when it worked. The occasional thanks from users is also
very satisfying.

There are several paths forward for a new maintainer:

  1. Learn all the current code, and maintain it.

  2. Drop the wisitoken parser generator and runtime, use tree-sitter
    instead. This requires writing a wrapper for tree-sitter to match
    the wisitoken syntax-tree API; then the current wisi indentation
    code can be used.

    This maintains all of the ada-mode features, while reducing the
    maintenance burden significantly.

    I believe the tree-sitter error correction is less powerful than
    wisitoken, but it would be interesting to see if that matters in

  3. Drop everything except the grammar; use tree-sitter parser and
    emacs tree-sitter queries for indentation, face, navigation.

    It will not be possible to match the current ada-mode indentation
    styles, and some ada-mode features will be lost. Even more
    maintenance burden reduction.

  4. Just use eglot and AdaCore ada_language_server.

    Even larger deviation from current styles, even more features lost.
    But could work with AdaCore to improve things; that would also
    improve GNAT Studio.

If you are interested in handling all or part of this work, contact me
via the Emacs ada-mode mailing list
(Emacs Ada mode - Mailing Lists [Savannah]) or directly at
[email protected].

3 posts - 3 participants

Read full topic

Review my code: Thick bindings to libusb

26 October 2023 at 19:27


I started learning Ada about 2 weeks ago and these thick bindings to libusb is my first Ada project.

I can now neatly iterate over connected USB devices. I only added enough functionality to list USB devices but will add more in the near future.

Please spare a few minutes to review my code and let me know what I’m doing wrong, what I should do differently, what can be improved, etc.

For example, I’m not sure if I should collect all type definitions at the beginning of the package or intersperse them between function declarations.

2 posts - 2 participants

Read full topic

Type and variable naming

26 October 2023 at 16:39

Is there a convention for naming types and variables?

For example, I have a type named Context which means that I can’t name a variable below Context. I could rename type to Context_Type but then would need to add _Type to the rest of the types in this library lest I be inconsistent.

Alternatively, I can name the variable Ctx and leave the type as Context (also Dev : Device, Devices : Device_List, etc.) which is the approach I’m taking now.

What is the canonical Ada way? I much prefer to use full variable names (in Ada) as opposed to abbreviations. I’m trying to follow the AdaCore naming approach as much is possible but it fails in the case above.

  function Init (Context : out Context) return C.int with
   Import => True, Convention => C, External_Name => "libusb_init";

And a follow-up example below…

I can’t have a Device_Descriptor since that’s a record type in my library. I decided to use the _Kind suffix but I’m not happy about it.

type Descriptor_Kind is

21 posts - 10 participants

Read full topic

Implementing Release for GNATCOLL.Refcount

19 October 2023 at 15:28

GNATCOLL.Refcount provides a procedure to run some code when the reference-counted element is released.

How do I implement this procedure?

I’m clearly missing something because Release is not visible as GNATCOLL.Refcount.Release and this doesn’t work

type Context_Contents is new GNATCOLL.Refcount.Refcounted with record
    Address : System.Address;
end record;

procedure Release is new GNATCOLL.Refcount.Release
   (Self => Context_Contents);

and gives me

usb.ads:29:47: error: "Release" not declared in "Refcount"

4 posts - 3 participants

Read full topic

What exceptions are thrown?

19 October 2023 at 05:46

How do I find out what exceptions a procedure or function throws?

Is there a language construct like “throws” in C++ or is it up to the developer to document this in comments?

I’m wrapping a C library that returns a handle in an argument unless the error code returned is non-zero. I would rather not have users of my library check for null handles so I thought I would convert errors to Ada exceptions. Is this the way to go?

18 posts - 7 participants

Read full topic

VSCode formatting

17 October 2023 at 13:56

Good day folks!

Is this canonical Ada formatting or is there a way to improve it in Visual Studio Code?

  type Size is
    (Device, Config, Intface, Endpoint, Audio_Endpoint, HUB_NonVAR,
     SS_Endpoint_Companion, BOS, Capability);
  for Size use
    (Device         => 18, Config => 9, Intface => 9, Endpoint => 7,
     Audio_Endpoint => 9, HUB_NonVAR => 7, SS_Endpoint_Companion => 6,
     BOS            => 5, Capability => 3);
  for Size'Size use Interfaces.C.unsigned_char'Size;
Thanks, Joel

13 posts - 5 participants

Read full topic