"invalid prefix" nonsense that disappears if the unit's generic part is omitted

gcc/gnat is having a seizure on me:

drm@84-47-09-37-40-35 ~> gnatmake main.ads
gcc -c main.ads
main.ads:10:127: error: invalid prefix in selected component “X”
main.ads:10:147: error: invalid prefix in selected component “X”
main.ads:10:168: error: invalid prefix in selected component “Y”
main.ads:10:186: error: invalid prefix in selected component “Y”
gnatmake: “main.ads” compilation error

for this:

pragma Extensions_Allowed (All);
generic
   type Element is private;     -- assignment and equality predefined
package main is
   type Data is record
      X,Y: Positive;
      E: Integer;
   end record;
   type ArrayInput is array (Positive range 1..<>) of Data with Predicate => (for all I in 2..ArrayInput'Last => ArrayInput(I).X < ArrayInput(I-1).X or ArrayInput(I-1).Y < ArrayInput(I).Y);
end main;

Remove the generic part, on which nothing depends anyway, and it compiles. Same with Dynamic_Predicate. Do I file a bug report ?

I am no Ada expert, so take what I am about to say with a huge grain of salt… But I believe generics can only be part of packages as they need to be instantiated and GNAT will, during compilation time, specialise the generic package/methods for the instantiated type. If you are doing this directly in the main file, GNAT may be going crazy and missreporting the error…

Best,
Fer

It’s a generic spec that happens to be called Main, which is confusing but not wrong.

It looks as though GCC 14 can’t handle the fixed lower bounds for arrays and suptypes extension in generics.

An early draft GCC 15 (from July) says

main.ads:1:28: error: argument for pragma "Extensions_Allowed"
 must be "On" or "Off" or "All_Extensions"

Sadly, pragma Extensions_Allowed (All_Extensions); continues to fail, but at least gnatpp & gnatformat work OK.

I tried building a recent GCC 15 earlier today, but I got the build wrong :frowning:

sigh… Compilers really are touchy programs, aren’t they ? I can only pity those working on them.

You get the same errors from GNAT 14.1 even if you use Ada:

generic
   type Element is private;     -- assignment and equality predefined
package Predicate_Test is
   type Data is record
      X,Y: Positive;
      E: Integer;
   end record;
   type Arrayinput is array (Positive range <>) of Data with
      Dynamic_Predicate => Arrayinput'First = 1 and then
                           (for all I in Arrayinput'First + 1 .. Arrayinput'Last => Arrayinput (I).X < Arrayinput (I - 1).X or
                                                                                    Arrayinput (I - 1).Y < Arrayinput (I).Y);
end Predicate_Test;

No errors if the package is not generic.

Not fixed in GNAT 15.0.0 20241102 (experimental) (but the errors are different).

Would you like [me] to raise a PR?

     1. pragma Extensions_Allowed (On);
     2. generic
     3. package Main is
     4.    type Data is record
     5.       X, Y : Positive;
     6.       E    : Integer;
     7.    end record;
     8.    type ArrayInput is array (Positive range 1 .. <>) of Data with
     9.      Predicate =>
    10.       (for all I in 2 .. ArrayInput'Last =>
    11.          ArrayInput (I).X < ArrayInput (I - 1).X or
                 1                  2
        >>> error: reference to current instance of type does not denote a type (RM 8.6)
        >>> error: reference to current instance of type does not denote a type (RM 8.6)

    12.          ArrayInput (I - 1).Y < ArrayInput (I).Y);
                 1                      2
        >>> error: reference to current instance of type does not denote a type (RM 8.6)
        >>> error: reference to current instance of type does not denote a type (RM 8.6)

    13. end Main;

(by the way, that’s the output of -gnatl, very helpful for reporting errors (if verbose))

3 Likes

I’d suggest testing this on the Ada equivalent that I posted before reporting it. As you have GNAT 15.0 and I don’t, I think you should file the ticket.

Just a side note, that everyone with an internet connection can try at least small things out on the most recent GCC using https://godbolt.org/

Use the x86-64 gnat (trunk) target

I’ve submitted quite a few PRs showing the results from godbolt and they have been received well. If you ever want to see the current version, then in the compiler switches section you can throw in a --version switch (you may first have to to do: Add new... into Execution Only from the menu to see the compiler output)

It’s also useful to see when a bug started as godbolt provides multiple versions to test (not all, but a lot).

And tip: The default filename godbolt uses is example.adb so you can highlight all the default crap and replace it with

procedure Example is
begin
   null;
end Example;

and go from there.

2 Likes

Sorry, I thought I was replying to @evanescente-ondine.

I guess you’re referring to the use of Predicate instead of Dynamic_Predicate? But that’s a GNAT extension, and this is a GNAT compiler.

I tried both anyway :nerd_face:
This all-compiler tool is extra useful, thank you jere. I can’t bring myself to open and study several books at once, so I haven’t come to debugging and debugging tools, or much of the compiler and associated ecosystem beyond default switches and gnatmake/alr run, so I can’t help much here. But I’m sure I’ll enjoy it when I’ll be there.
File it, by all means.

I was referring to the use of pragma Extensions_Allowed, the half-constrained array type notation, and the use of 'Predicate`. Really, when using the GNAT extensions, you’re using an Ada-like language with semantics determined by AdaCore, so maybe the error message is correct in that case.

I’ve tried the Ada version with GNAT 15 on godbolt with the same results.

ObjectAda 10.5 compiles the Ada version without error.

What ? No, removing the extensions produces the same error. I had tried that.

pragma Ada_2012;
generic
   type Element is private;     -- assignment and equality predefined
package main is
   type Data is record
      X,Y: Positive;
      E: Integer;
   end record;
   type ArrayInput is array (Positive range <>) of Data with Dynamic_Predicate => (for all I in 2..ArrayInput'Last => ArrayInput(I).X < ArrayInput(I-1).X or ArrayInput(I-1).Y < ArrayInput(I).Y);
end main;

Raised GCC PR 117569.


(By the way, because a GCC PR = “Problem Report” while a Github PR = “Pull Request”, some people have taken to calling the former a BZ (Bugzilla))