1----------------------------------------------------------------- 2-- file: bug.adb [$Revision: 110555 $] 3----------------------------------------------------------------- 4 5-- Demonstrates incorrect implementation of record assignment. 6-- The bug appears at least in GNAT 3.10p, 7-- and the version of 3.11w we are using here (FSU). 8-- This problem seems to depend on: 9-- the alignment clause 10-- the representation clause 11-- the aliased component 12 13-- On Solaris 2.6 SuperSPARC (Sparcstation 20 HS14) the test 14-- fails, and prints: 15 16-- dad% ERROR: record assignment does not copy C.s_addr correctly. 17-- Addr.C.s_addr= 1 18-- Tmp_Addr.in_addr.sin_addr.s_addr= 0 19-- Assignment works OK at leaf component level. 20-- Tmp_Addr.in_addr.sin_addr.s_addr= 1 21 22-- This bug came up in the Florist POSIX sockets interface. 23 24-- --Ted Baker (baker@cs.fsu.edu) 25 26with Ada.Text_IO; 27procedure bug is 28 29 ALIGNMENT : constant := 8; 30 type int16 is range -2**15 .. 2**15 - 1; 31 32 type in_addr_t is mod 2**32; 33 34 type struct_in_addr is record 35 s_addr : in_addr_t; 36 end record; 37 for struct_in_addr'Alignment use ALIGNMENT; 38 39 type Internet_Address is record 40 C : struct_in_addr; 41 end record; 42 43 type struct_sockaddr_in is record 44 sin_family : int16; 45 sin_port : int16; 46 sin_addr : struct_in_addr; 47 sin_zero : String (1 .. 8); 48 end record; 49 for struct_sockaddr_in use record 50 sin_family at 0 range 0 .. 15; 51 sin_port at 2 range 0 .. 15; 52 sin_addr at 4 range 0 .. 31; 53 sin_zero at 8 range 0 .. 63; 54 end record; 55 56 type Internet_Socket_Address is record 57 in_addr : aliased struct_sockaddr_in; 58 end record; 59 60 Addr : Internet_Address; 61 Tmp_Addr : Internet_Socket_Address; 62 63begin 64 65 Addr.C.s_addr := 1; 66 Tmp_Addr.in_addr.sin_addr := Addr.C; 67 68 if Tmp_Addr.in_addr.sin_addr.s_addr /= Addr.C.s_addr then 69 Ada.Text_IO.Put_Line 70 ("ERROR: record assignment does not copy C.s_addr correctly."); 71 Ada.Text_IO.Put_Line ("Addr.C.s_addr=" & 72 in_addr_t'Image (Addr.C.s_addr)); 73 Ada.Text_IO.Put_Line 74 ("Tmp_Addr.in_addr.sin_addr.s_addr=" & 75 in_addr_t'Image (Tmp_Addr.in_addr.sin_addr.s_addr)); 76 Tmp_Addr.in_addr.sin_addr.s_addr := Addr.C.s_addr; 77 if Tmp_Addr.in_addr.sin_addr.s_addr = Addr.C.s_addr then 78 Ada.Text_IO.Put_Line 79 ("Assignment works OK at leaf component level."); 80 Ada.Text_IO.Put_Line 81 ("Tmp_Addr.in_addr.sin_addr.s_addr=" & 82 in_addr_t'Image (Tmp_Addr.in_addr.sin_addr.s_addr)); 83 end if; 84 else 85 Ada.Text_IO.Put_Line ("Assignment works OK."); 86 end if; 87 88end bug; 89