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