Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Alleged GNAT bug

205 views
Skip to first unread message

Victor Porton

unread,
Oct 20, 2017, 2:10:28 PM10/20/17
to
I've reported the following GNAT bug:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82639

I state that a legal program fails with a compiler error message.

But please confirm if my program (see above URL) is really legal. Maybe I
mistake?

--
Victor Porton - http://portonvictor.org

A. Cervetti

unread,
Oct 24, 2017, 6:13:55 AM10/24/17
to
>
> I state that a legal program fails with a compiler error message.
>
> But please confirm if my program (see above URL) is really legal. Maybe I
> mistake?

No, it is not.

The reason is not obvious and a little convoluted (like your program too) and depend upon the freezing rules (arm 13.14)
Anyway the reference to System.ads in the error message is misleading.

In the generic package With_Finalization you derive the type Derived from the formal Base type. Derived is a record extension (although null) of the base type.

This means that, when you instantiate the package the actual Term_Type_Without_Finalize is frozen (13.14.7).

The compiler tries to create a dispatch table for the primitive operation of the type.

Get_Literal is a primitive operation so it is frozen too (13.14.15 1/3) but the return type Term_Literal_Value is still incomplete (7.3.5)

The ARM is not explicit about this (as far as I know, any language lawyer out there?) but the reason of the error is as I said.

To avoid the error you should instantiate the package Finalizer after the completion of Term_Literal_Value.

if you need visibility of Term_Type you can declare it as private too.

....
type Term_Type is private;

private

type Term_Literal_Value is null record;

package Finalizer is new Term_Handled_Record.With_Finalization(Term_Type_Without_Finalize);

type Term_Type is new Finalizer.Derived with null record;
....


This works.

A.

Randy Brukardt

unread,
Oct 24, 2017, 7:08:34 PM10/24/17
to
"A. Cervetti" <andrea....@gmail.com> wrote in message
news:2be64a8b-5f89-414c...@googlegroups.com...
...
> The ARM is not explicit about this (as far as I know, any language lawyer
> out there?)
> but the reason of the error is as I said.

That can't be right, because incomplete types aren't frozen; they have their
own custom set of Legality Rules which is much stronger. (We - the ARG -
confused ourselves about this for a decade until we gave up and changed back
to the simple model.)

So the actual error ought to be something in 3.10.1, if the type in
incomplete.

OTOH, the type is a *partial* view (like a private type), then the freezing
rules do apply, specifically 13.14(17) or 7.3(5) or 3.11.1(8). The Ada 9x
team thought this was so important they repeated it three times.

Randy.

P.S. I didn't actually look at the program, only the analysis. So the
analysis could be way wrong. Too sick to take on extra work...


A. Cervetti

unread,
Oct 24, 2017, 8:53:26 PM10/24/17
to
I apologize.

I reworked the code in a single program:
---------------------------------------------------------------------------
with Ada.Finalization;

procedure My_Test is

generic
package Handled_Record is
type Base_Object is new Ada.Finalization.Controlled with null record;
not overriding procedure Finalize_Handle(Object: Base_Object) is null;

generic
type Base is new Base_Object with private;
package With_Finalization is
type Derived is new Base with null record;
end;
end Handled_Record;

package Term is
package Term_Handled_Record is new Handled_Record;
type Term_Type_Without_Finalize is
new Term_Handled_Record.Base_Object with null record;
overriding procedure Finalize_Handle (Object: Term_Type_Without_Finalize);
type Term_Kind is (Literal);
type Term_Literal_Value is private;
not overriding function Get_Literal (Term: Term_Type_Without_Finalize)
return Term_Literal_Value;
package Finalizer is new
Term_Handled_Record.With_Finalization(Term_Type_Without_Finalize);
type Term_Type is new Finalizer.Derived with null record;
private
type Term_Literal_Value is null record;
end Term;

package body Term is
function Get_Literal (Term: Term_Type_Without_Finalize)
return Term_Literal_Value is
begin
return (null record);
end;
procedure Finalize_Handle (Object: Term_Type_Without_Finalize) is
begin
null;
end;
end Term;
begin
null;
end My_Test;
--------------------------------------------------------------------------

Compiling with gnat 4.9.3 crashes the compiler (Storage_Error stack overflow or erroneous memory access at my_test.adb:3:1)

Compiling with gnat-2017 from libre.adacore.com the compilation goes well (obviously it does nothing).

The original code is split in three modules (handled_record.ads, term.ads, term.adb).

With both compilers it give the error:
system.ads:1:01: declaration must appear after completion of type "Term_Literal_Value"
gnatmake: "term.adb" compilation error

Removing the lines:
type Derived is new Base with null record;
and
type Term_Type is new Finalizer.Derived with null record;

from my_test.adb and from the original modules the compilation goes well.

Also with the modification I suggested in my first post the compilation goes well in both versions.

So I conclude:
The error happens at the freezing point, but with gnat-2017 only in the modular version.
The code could be legal because it works in the monolithic version, but after reading Randy's message I am no more sure of anything.

> Too sick to take on extra work...

Sorry to hear this, I hope you will be well soon.

A.

AdaMagica

unread,
Oct 25, 2017, 1:03:24 PM10/25/17
to
Am Mittwoch, 25. Oktober 2017 02:53:26 UTC+2 schrieb A. Cervetti:
> So I conclude:
> The error happens at the freezing point, but with gnat-2017 only in the modular version.
> The code could be legal because it works in the monolithic version, but

I guess you are right. Exporting the last instantiation Finalizer to a child makes the program legal.

package Term.Child is

package Finalizer is new Term_Handled_Record.With_Finalization(Term_Type_Without_Finalize);

type Term_Type is new Finalizer.Derived with null record;

end Term.Child;

An instantiation seems to freeze the actual type 13.14(5/3), and Term_Type_Without_Finalize has a primitive operation involving an incomplete type. 13.14(10.2/4) does not apply here IMO.

But I'm in no way a language lawyer, and 13.14 is the heart of darkness.

As a side note I must say, I'm completely confused about the namings in this code. The type Base_Object is already finalized, and any and all further derivations do not add more finalizing code.

Victor Porton

unread,
Oct 25, 2017, 1:28:05 PM10/25/17
to
AdaMagica wrote:

> Am Mittwoch, 25. Oktober 2017 02:53:26 UTC+2 schrieb A. Cervetti:
>> So I conclude:
>> The error happens at the freezing point, but with gnat-2017 only in the
>> modular version. The code could be legal because it works in the
>> monolithic version, but
>
> I guess you are right. Exporting the last instantiation Finalizer to a
> child makes the program legal.

By "you are right" you mean "The code could be legal", don't you?

Or what do you mean?

> package Term.Child is
>
> package Finalizer is new
> Term_Handled_Record.With_Finalization(Term_Type_Without_Finalize);
>
> type Term_Type is new Finalizer.Derived with null record;
>
> end Term.Child;
>
> An instantiation seems to freeze the actual type 13.14(5/3), and
> Term_Type_Without_Finalize has a primitive operation involving an
> incomplete type. 13.14(10.2/4) does not apply here IMO.
>
> But I'm in no way a language lawyer, and 13.14 is the heart of darkness.
>
> As a side note I must say, I'm completely confused about the namings in
> this code. The type Base_Object is already finalized, and any and all
> further derivations do not add more finalizing code.

This is a shortened version of a real Ada2012 code available at
https://github.com/vporton/redland-bindings/tree/ada2012

Thus the naming.

AdaMagica

unread,
Oct 26, 2017, 3:09:40 AM10/26/17
to
Am Mittwoch, 25. Oktober 2017 19:28:05 UTC+2 schrieb Victor Porton:
> AdaMagica wrote:
>
> > Am Mittwoch, 25. Oktober 2017 02:53:26 UTC+2 schrieb A. Cervetti:
> >> So I conclude:
> >> The error happens at the freezing point, but with gnat-2017 only in the
> >> modular version. The code could be legal because it works in the
> >> monolithic version, but
> >
> > I guess you are right. Exporting the last instantiation Finalizer to a
> > child makes the program legal.
>
> By "you are right" you mean "The code could be legal", don't you?
>
> Or what do you mean?

Of course I mean that the problem is the freezing point - your program is illegal. With the proposed change Term.Child, it is legal.

Victor Porton

unread,
Oct 26, 2017, 2:41:42 PM10/26/17
to
But the monolithic version DOES compile. Is THIS (that it does compile) an
error in GNAT?

Randy Brukardt

unread,
Nov 14, 2017, 6:35:42 PM11/14/17
to
"AdaMagica" <christ-u...@t-online.de> wrote in message
news:b1204442-ba3e-4a37...@googlegroups.com...
...
> But I'm in no way a language lawyer, and 13.14 is the heart of darkness.

Please don't confuse people. 3.10.2 (accessibility rules) is the Heart of
Darkness. See AARM 3.10.2(3.b/3). (I'm serious.)

Freezing rules are *way* easier to understand (not to claim that they're
easy).

Anyway, an instantiation freezes many things, so that can change the effects
around a lot. I thought the original case didn't have anything to do with an
instance.

Randy.


Robert Eachus

unread,
Nov 16, 2017, 10:55:49 AM11/16/17
to
On Tuesday, November 14, 2017 at 6:35:42 PM UTC-5, Randy Brukardt wrote:

> Please don't confuse people. 3.10.2 (accessibility rules) is the Heart of
> Darkness. See AARM 3.10.2(3.b/3). (I'm serious.)

I'd include the whole 3.10.2 Static Semantics section. It is amazing how much verbiage is required to correctly state what was originally assumed to be an implicit result of static nesting. Allowing an access type to designate a more deeply nested type is clearly wrong. The problem is all in defining 'more deeply.'
0 new messages