Hello, The Ada testcase below, compiled with -O2 on x86-linux, triggers a SEGV in the current mainline compiler, there:
do_simple_structure_copy { ... for (; p && p->offset < last; p = p->next) { ... q = first_vi_for_offset (q, q->offset + fieldoffset); ==> temprhs.var = q->id; Below is a description of what is going on, plus suggestions on how to address the problem. I'd welcome feedback before submitting a patch with all the required testing process. The test basically constructs a record type with two 6bits long components, each of a record type also, and the two components (called key1 and key2) are tighly packed with a representation clause (no hole between the two components). Something like: 6bits 6bits |.......|.......| key1 key2 Eventhough the field *decls* specify a 6bits length, the *type* of each is actually QI integer (8bits long). The SEGV above triggers on an assignment to a .key1 component from a standalone variable of the corresponding type. This is Keys.One_Pair.Key1 := Keys.One_Key; in k.adb. Several factors come into play, AFAICS: o the incoming 'size' argument is based on type and not decl information, and is used to bound the iteration (to compute 'last') o the offset increments for each component within the loop are based on decl size information o .key2 appears as a successor of .key1 in the lhs because they are part of the same outer object. We remain in the for loop after processing the assignment to .key1 because the decl size is strictly smaller than the type size, so 'last' is not reached, and there is a 'next' variable in sight. But then, we're out of the source standalone variable contents, so first_vi_for_offset returns null and we SEGV on the dereference. A very simple way to deal with this is to just 'break' out of the loop when 'q' happens to be null, with an appropriate comment briefly explaining how this could happen. Another way would be to compute the incoming 'size' argument from decl information when appropriate. This seems more involved at first sight. Thanks in advance for your help, Olivier -- $ gcc -c -O2 k.adb -- raised STORAGE_ERROR : stack overflow (or erroneous memory access) with Keys; procedure K is begin Keys.One_Pair.Key1 := Keys.One_Key; end; package Keys is Key_Size : constant := 6; type Key_Value_T is range 0 .. 2 ** Key_Size - 1; for Key_Value_T'Size use Key_Size; type Key_T is record Value : Key_Value_T; end record; for Key_T use record Value at 0 range 0 .. Key_Size - 1; end record; type Key_Pair_T is record Key1, Key2 : Key_T; end record; for Key_Pair_T use record Key1 at 0 range 0 .. Key_Size - 1; Key2 at 0 range Key_Size .. Key_Size + Key_Size - 1; end record; One_Key : Key_T := (Value => 1); One_Pair : Key_Pair_T; end;