1
votes

I expected the following code to throw a constraint error on compilation, however it didn't. It also does not throw a runtime error on the c2 assignment. Edit: Running the compiler with -gnata solves the compilation warning issue, but does not solve the lack-of runtime error issue. It is compiled using GNAT FSF with no optimizations, just: gnatmake main Edit: gnatmake -gnata main

with Ada.Text_IO; use Ada.Text_IO;

procedure Main is
    subtype cat is Integer with Dynamic_Predicate => cat in 1 .. 9;

    c1 : cat;
    c2 : cat;
begin
    c1 := 5;
    c2 := 99;
end Main;

I thought that the Dynamic_Predicate line would essentially be equivalent to the following :

subtype cat is Integer range 1 .. 9;
1
@PaulCrovella The question that you are quoting answers the lack-of compilation error issue, but does not address why a runtime error is not produced when the program is actually executed. - user3117351
You could make the predicate static. The expression is one of those allowed for static predicates. - Jacob Sparre Andersen
Which FSF GCC are you using? - Simon Wright
@SimonWright I am using TDM-GCC-64, which is gcc version 5.1.0 (tdm64-1). This is through the git bash terminal on Windows 10 pro. - user3117351

1 Answers

3
votes

When I build your example, I get a compile-time warning, and a run-time error:

$ gnatmake -gnata -gnato -fstack-check -gnat12 -gnatyO -gnatv -gnati1 -gnatf -gnatn -m -j0 main.adb
gcc-6 -c -gnata -gnato -fstack-check -gnat12 -gnatyO -gnatv -gnati1 -gnatf -gnatn main.adb

GNAT 6.3.0 20170516
Copyright 1992-2016, Free Software Foundation, Inc.

Compiling: main.adb
Source file time stamp: 2018-08-02 06:08:55
Compiled at: 2018-08-02 08:11:00

    10.     c2 := 99;
                  |
        >>> warning: expression fails predicate check on "cat"

 11 lines: No errors, 1 warning
gnatbind-6 -x main.ali
gnatlink-6 main.ali -fstack-check
$ ./main

raised SYSTEM.ASSERTIONS.ASSERT_FAILURE : Dynamic_Predicate failed at main.adb:10
$ 

I quess your problem is that the default assertion policy in GCC/GNAT is Ignore. I use the flag -gnata to override that.

Notice that the compiler only gives you a warning. That's because the program is completely legal, even if it will raise an exception at run-time. (This is the same, no matter if you use range, Static_Predicate or Dynamic_Predicate to specify the subset.)