Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unexpected CONSTRAINT_ERROR after GCC update

Tags:

gcc

ada

gnat

We recently updated GCC versions (4.8.2 to 5.3.0) and started receiving unexpected constraint errors in some Ada applications. I've reduced it to the following:

-- moo.adb
with text_io;
procedure moo is
   type thing_type is (something1,something2,something3,something4,something5,something6);
   for thing_type use (something1 => 1,something2 => 2,something3 => 
      3,something4 => 4,something5 => 5,something6 => 6);
   for thing_type'size use 32;
   type thing_array_t is array (0 .. 5) of thing_type;
   thing_array : thing_array_t := (others => something1);
begin
   text_io.put_line("item 0 = " & thing_type'image(thing_array(0)));
end moo;

This program will compile just fine on either GCC version (simply compiled with "gnatmake moo.adb".) When built with 4.8.2, the output is as expected:

item 0 = SOMETHING1

When built with 5.0.3, we instead receive

raised CONSTRAINT_ERROR : moo.adb:13 invalid data

Interestingly, the results are exactly the same when compiled as 32 and 64 bit. Many things can be changed to make the program work fine with 5.3.0: removing the thing_type'size clause, adding or removing values to the enumerator, changing the number of items in the array, using a different value for initializing the array, etc. Are there any obvious problems with this code that could account for this behavior?

like image 983
Kevin Avatar asked Mar 14 '26 21:03

Kevin


1 Answers

This bug is still present in GCC 7.0.1. Running under the debugger, output slightly edited,

(gdb) catch exception
Catchpoint 2: all Ada exceptions
(gdb) run
Starting program: /Users/simon/tmp/so/moo 
[New Thread 0x1703 of process 75511]

Catchpoint 2, CONSTRAINT_ERROR (moo.adb:10 invalid data) at 0x0000000100001abe in _ada_moo () at moo.adb:10
10     text_io.put_line("item 0 = " & thing_type'image(thing_array(0)));
(gdb) p thing_array
$5 = (0 => 16843009, 16843009, 16843009, 16843009, 16843009, 16843009)
(gdb) p/x thing_array
$6 = (0 => 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101, 0x1010101)

so GNAT has mistakenly set each byte of thing_array elements to 16#01#, rather than the whole element.

The same happens if something1 is set to 2 (and later values incremented, likewise).

The only thing I can find that helps is to declare, for example,

type base_thing_type is (invalid, something1,something2,something3,something4,something5,something6);
for base_thing_type use (invalid => 0, something1 => 1,something2 => 2,something3 =>
                      3,something4 => 4,something5 => 5,something6 => 6);
for base_thing_type'size use 32;
type thing_type is new base_thing_type range something1 .. something6;
like image 165
Simon Wright Avatar answered Mar 17 '26 17:03

Simon Wright



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!