2017-03-15 1 views
2

Nous avons récemment mis à jour les versions de GCC (4.8.2 à 5.3.0) et commencé à recevoir des erreurs de contraintes inattendues dans certaines applications Ada. Je l'ai réduit à ce qui suit:CONSTRAINT_ERROR inattendu après la mise à jour de GCC

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

Ce programme compilera très bien sur les deux versions de GCC (simplement compilé avec « gnatmake moo.adb ».) Une fois construit avec 4.8.2, la sortie est comme prévu :

item 0 = SOMETHING1 

Une fois construit avec 5.0.3, nous recevons à la place

raised CONSTRAINT_ERROR : moo.adb:13 invalid data 

Fait intéressant, les résultats sont exactement les mêmes que lors de la compilation 32 et 64 bits. Beaucoup de choses peuvent être modifiées pour que le programme fonctionne correctement avec 5.3.0: supprimer la clause thing_type'size, ajouter ou supprimer des valeurs dans l'énumérateur, changer le nombre d'éléments dans le tableau, utiliser une valeur différente pour initialiser le tableau, etc. Y at-il des problèmes évidents avec ce code qui pourrait expliquer ce comportement?

+0

Quelle est la ligne 13? (Votre liste ne contient que 12 lignes.) –

+0

Désolé, j'ai supprimé des lignes vides de l'original lorsque je l'ai collé. La ligne 13 est la ligne text_io. – Kevin

Répondre

6

Ce bug est toujours présent dans GCC 7.0.1. Fonctionnant sous le débogueur, sortie légèrement modifié,

(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) 

si GNAT a fixé par erreur chaque octet de thing_array éléments à 16#01#, au lieu de l'élément entier.

La même chose se produit si something1 est définie sur 2 (et les valeurs ultérieures sont incrémentées de la même manière).

La seule chose que je peux trouver qui aide est de déclarer, par exemple,

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

Merci Simon, je vais soumettre un rapport de bug à GCC – Kevin

+0

Kevin, avez-vous déjà signalé ce bug? Il est toujours présent dans GCC 8.0.0 20171216 –

4

Cela ressemble à un bug dans GCC/GNAT. Je peux reproduire le comportement incorrect avec GNAT-GPL-2016 en mode conforme standard (-gnato -fstack-check -gnat12). La partie critique semble être que Something1 est représenté par 1 au lieu du plus typique 0. Je suggère que vous signaliez le bug aux développeurs de GCC.

+0

Merci, rapport de bug c'est :( – Kevin