2017-03-15 3 views
2

Wir haben kürzlich die GCC-Versionen (4.8.2 bis 5.3.0) aktualisiert und haben in einigen Ada-Anwendungen unerwartete Constraint-Fehler erhalten. Ich habe es auf das folgende reduziert:Unerwarteter CONSTRAINT_ERROR nach GCC-Update

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

Dieses Programm entweder auf GCC-Version nur übersetzt werden können (einfach zusammengestellt mit „gnatmake moo.adb“). Wenn mit 4.8.2 gebaut, wird die Ausgabe wie erwartet :

item 0 = SOMETHING1 

wenn mit 5.0.3 gebaut, erhalten wir statt

raised CONSTRAINT_ERROR : moo.adb:13 invalid data 

Interessanterweise weise~~POS=HEADCOMP sind die Ergebnisse genau das gleiche, wenn es als 32- und 64-Bit kompiliert. Viele Dinge können geändert werden, damit das Programm mit 5.3.0 funktioniert: Entfernen der thing_type'size-Klausel, Hinzufügen oder Entfernen von Werten zum Enumerator, Ändern der Anzahl der Elemente im Array, Verwenden eines anderen Werts für die Initialisierung des Arrays, etc Gibt es offensichtliche Probleme mit diesem Code, die dieses Verhalten erklären könnten?

+0

Was 13 on line? (Ihr Eintrag hat nur 12 Zeilen.) –

+0

Entschuldigung, ich entfernte einige leere Zeilen aus dem Original, als ich es eingefügt habe. Zeile 13 ist die Zeile text_io. – Kevin

Antwort

6

Dieser Fehler ist immer noch in GCC 7.0.1 vorhanden. Läuft unter dem Debugger, Ausgang, leicht bearbeitet

(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 hat GNAT gesetzt fälschlicherweise jedes Byte von thing_array Elemente 16#01#, anstatt das gesamte Element.

Das gleiche passiert, wenn something1 auf 2 gesetzt ist (und spätere Werte ebenfalls inkrementiert).

Das einzige, was ich finden kann, das hilft zu erklären, zum Beispiel

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; 
+0

Danke Simon, ich werde einen Fehlerbericht an GCC senden. – Kevin

+0

Kevin, hast du diesen Fehler jemals gemeldet? Er ist immer noch in GCC 8.0.0 20171216 enthalten –

4

Es sieht aus wie ein Fehler in GCC/GNAT. Ich kann das falsche Verhalten mit GNAT-GPL-2016 im standardkonformen Modus replizieren (-gnato -fstack-check -gnat12). Der kritische Teil scheint zu sein, dass Something1 als 1 statt der typischen 0 dargestellt wird. Ich schlage vor, dass Sie den Fehler den GCC-Entwicklern melden.

+0

Danke, Fehlerbericht ist :( – Kevin