❌ About FreshRSS

Normal view

There are new articles available, click to refresh the page.
Before yesterdayNews from the Ada programming language world

How does one override an operation with classwide types?

By: jere
28 December 2023 at 17:38

I didn’t think it was possible, but some annotations in the annotated RM seem to indicate it is possible. I’m working with subpools and I want to create some of my own for non heap objects. The problem is that in GNAT they use heap allocation in the function Set_Pool_of_Subpool, which is a required call, so if it is possible to override this, then I would like to so I can have it avoid heap allocation.

For reference from System.Storage_Pools.Subpools:

type Subpool_Handle is access all Root_Subpool'Class;
   for Subpool_Handle'Storage_Size use 0;

function Pool_of_Subpool (Subpool : not null Subpool_Handle)
      return access Root_Storage_Pool_With_Subpools'Class;

procedure Set_Pool_of_Subpool (
      Subpool : in not null Subpool_Handle;
      To : in out Root_Storage_Pool_With_Subpools'Class)
         with Global => overriding in out Subpool;

And the RM annotation (Ada22 annotated RM 20.a/3):

Discussion: Pool_of_Subpool and Set_Pool_of_Subpool are provided by the Ada 
implementation and typically will not be overridden by the pool implementer. 

There is uses the phrasing β€œtypically” which would imply that they could be overridden by an implementer for some cases.

The only way I could come up to override it was to create a derived type of the handle but then the compiler complains when I use β€œnew” with the derived subpool handle type that the handle type isn’t the standard one, so I don’t think that is what the discussion point was referring to (as it would be pointless to override in this way).

To my knowledge you can’t override operations with classwide types. Anyone have any insight into this?

Subpools reference: Storage Subpools

1 post - 1 participant

Read full topic

Running RecordFlux

28 December 2023 at 08:30

I’m writing a protocol parser and would like to use RecordFlux to generate a parser from a specification. I’ve been unable to get any recent version of RecordFlux working with the GNAT toolchain from Alire. The wheel on pypi expects a GNAT Studio install with gnatcoll in the path and compiling from source seems to require and even deeper tree of manually built dependencies.

I’m begging anyone at AdaCore to write an alire.toml file.

1 post - 1 participant

Read full topic

Is there a good way to handle exceptioins in the declarative region of a function

By: jere
6 December 2023 at 21:46

While working on day 6 of AoC, I found myself breaking a larger calculation into parts and saving them as constants in the declarative region of the function. This was super clean for reading and let me document all my steps nicely. I also knew that if any of the steps failed, then my result should be 0. So I figured I would put an exception handler in the function and return 0 (Note that the case where exceptions happen would be pretty rare based on some really edge case inputs that weren’t practical to the problem):

The problem I ran into is if the early steps raised an exception, then the exception handler wouldn’t catch them as they were in the declarative region. See mock up below:

function Calculate(Inputs : Input_Type) return Integer is
   Step_1 : constant Integer := Some_Function(Stuff);
   Step_2 : constant Integer := Some_Other_Function(Stuff);
begin
   return Final_Function(Step_1, Step_2);
exception
   when others => return 0;  -- doesn't catch Step_1 or Step_2 exceptions!!!
end Calculate;

Any suggestions on a clean way to catch those declarative exceptions? I don’t like putting them in a declare block in the function body because that just indents everything needlessly. Currently I renamed my original function to old_name_unhandled and call it a new wrapper function named the original name, but that does feel kinda silly.

I was hoping there is an aspect or pragma maybe?

6 posts - 5 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:

example.adb:

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);

begin
    Put_Line("Hello World");
end Example;

test.ads:

generic
    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;

private

    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;

test.adb:

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
    begin
        return Map(Key).all;
    end Make;

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

begin
    Map.Insert(2,Thing_Access);
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.

10 posts - 3 participants

Read full topic

Advent of Code 2023

20 November 2023 at 03:59

It’s that time of year again!

Advent of Code is a series of daily programming puzzles from December 1st to 25th, becoming progressively more difficult each day. The puzzles can be completed in any programming language- inputs are short text files and the solutions are integers. Many people use these puzzles to learn a new language or try new techniques.

Last year, we had lively daily discussions and solutions in both Ada and SPARK on the forum. This year, I want to open the conversation up to any language with a focus on safety or reliability- Ada, SPARK, MISRA-C, or any other metallic compounds.

I think we can reuse last year’s leaderboard code 1708445-6a8f7730, which you can join on the Private Leaderboards page while logged into your AoC account.

5 posts - 3 participants

Read full topic

GNAT Pro Roadmap

7 July 2023 at 16:20

AdaCore posted an updated roadmap for GNAT Pro. Lots to look forward to here: LLVM, CUDA, FreeRTOS, Alire integration.

AdaCore Product Roadmap

6 posts - 6 participants

Read full topic

Buffered Streams

24 May 2023 at 02:13

I’ve been working on an application using GNAT.Sockets with calls to Receive_Socket and Send_Socket. I’ve been hesitant to use the Stream interface because I want writes coalesced into reasonably large (~64k) buffers for performance reasons.

I have my own buffered stream implemention right now, but I’m wondering if others have better solutions.

6 posts - 4 participants

Read full topic

GCC 13.1 Released

26 April 2023 at 23:20

https://gcc.gnu.org/pipermail/gcc-announce/2023/000175.html
https://gcc.gnu.org/gcc-13/changes.html

Ada specific changes:

  • Traceback support added in RTEMS for the PPC ELF and ARM architectures.
  • Support for versions older than VxWorks 7 has been removed.
  • General improvements to the contracts in the standard libraries.
  • Addition of GNAT.Binary_Search.
  • Further additions and fixes for the Ada 2022 specification.
  • The Pragma SPARK_Mode=>Auto is now accepted. Contract analysis has been further improved.
  • Documentation improvements

10 posts - 6 participants

Read full topic

OpenBSD gcc warnings

28 March 2023 at 23:46

I understand that this isn’t really a supported platform, but bear with me…

Using GNAT 11.2.0 built on the latest OpenBSD snapshot from their ports tree, I get the following warnings when compiling anything that links libgnat (line breaks added for readability):

adaint.c:572(adaint.o:(__gnat_try_lock) in archive /usr/local/lib/gcc/x86_64-unknown-openbsd7.3/11.2.0/adalib/libgnat.a):
warning: sprintf() is often misused, please use snprintf()
adaint.c:745(adaint.o:(__gnat_os_filename) in archive /usr/local/lib/gcc/x86_64-unknown-openbsd7.3/11.2.0/adalib/libgnat.a):
warning: strcpy() is almost always misused, please use strlcpy()
adaint.c:1358(adaint.o:(__gnat_readdir) in archive /usr/local/lib/gcc/x86_64-unknown-openbsd7.3/11.2.0/adalib/libgnat.a):
warning: stpcpy() is dangerous; do not use it
cstreams.c:253(cstreams.o:(__gnat_full_name) in archive /usr/local/lib/gcc/x86_64-unknown-openbsd7.3/11.2.0/adalib/libgnat.a):
warning: strcat() is almost always misused, please use strlcat()

I believe that this is good advice. strcat, strcpy, and sprintf are well known as sources of unsafe memory access.
CWE-158: Improper Neutralization of Null Byte or NUL Character
CWE-170: Improper Null Termination
CWE-676: Use of Potentially Dangerous Function

The Ada code calling into these functions does correctly allocate these buffers on the stack and initializes them with zeroes, and most of them pass a pointer to a length variable, initialized with the size of the buffer, to be updated with the length of the string after it’s value is determined.

Does it make sense to eliminate usage of these unsafe functions from libgnat, or am I overreacting? I’m working on a patch that fixes the few warnings I’ve run into, but I’m not sure how far this should go.

5 posts - 4 participants

Read full topic

wolfSSL Ada/SPARK language bindings

17 March 2023 at 05:35

I was looking for DTLS libraries and found this recent post on the wolfSSL website.

Exciting news in wolfSSL language bindings: we are currently exploring the possibility of adding bindings for the Ada and Spark languages!

Ada is a programming language known for its explicitness, strong typing, and abundance of compile-time checks. It is widely used in safety-critical and high-integrity software. Spark, on the other hand, is a smaller subset of Ada that offers the invaluable ability to formally prove the correctness of your software.

We believe that wolfSSL bindings would be immensely valuable to the Ada and Spark communities. These bindings would provide a production-ready, robust, and well-tested TLS stack that supports the latest protocols (TLS1.3/DTLS1.3). Additionally, it would open the door to obtaining FIPS 140-3 and DOI-178C certifications for Ada and Spark applications that use TLS for their encrypted communications, or that want to use our wolfCrypt implementation for their cryptographic operations, such as encrypting data at rest.

As wolfSSL already supports post-quantum TLS 1.3 and DTLS 1.3, these bindings would also naturally allow you to make your Ada and SPARK applications quantum-safe.

Are you interested in an Ada/Spark wrapper? If so, please do not hesitate to contact us at [email protected] with any questions, comments, or suggestions.

Source: wolfSSL ADA/Spark language bindings – wolfSSL

1 post - 1 participant

Read full topic

Advent of Computing Podcast

6 February 2023 at 05:25

This podcast did an episode about the origins of Ada.

I don’t like the way he pronounces Ada and I could be pedantic about some of the broad generalizations he makes, but overall I think this is a nice summary. Sounds like it’s going to be the beginning of a series, with a future episode about tasking. I’m looking forward to it!

8 posts - 6 participants

Read full topic

Architecture dependent representation clause

2 February 2023 at 21:43

I’m writing a wrapper around some Linux ioctl(2) calls and am using a representation clause to replace the macros in ioctl.h Β« asm-generic Β« uapi Β« include - kernel/git/stable/linux.git - Linux kernel stable tree

However, this header is architecture dependent and has different field sizes and constants for some older architectures: parisc, mips, powerpc, alpha, sparc.

   --  /usr/include/asm-generic/ioctl.h
   type IOC_DIR_Field is (None, Write, Read)
      with Size => 2;
   for IOC_DIR_Field use (0, 1, 2);
   --  parisc: Read and Write are swapped
   --  mips, powerpc, alpha, sparc: IOC_DIR_Field'Size = 3, Write is 4

   type IOC is record
      NR    : UInt8;
      TYP   : UInt8;
      SIZE  : UInt14;         --  13 bits on mips, powerpc, alpha, sparc
      DIR   : IOC_DIR_Field;  --  3 bits on mips, powerpc, alpha, sparc
   end record
      with Size => 32;
   for IOC use record
      NR    at 0 range 0 .. 7;
      TYP   at 1 range 0 .. 7;
      SIZE  at 2 range 0 .. 13;
      DIR   at 2 range 14 .. 15;
   end record;

Should I create a separate package for each architecture to define these fields, or is there a better way to make a representation clause architecture dependent?

6 posts - 3 participants

Read full topic

❌
❌