[Ada] Wrong size for variant records with single variant with front-end layout

Message ID 20120426094625.GA3907@adacore.com
State New
Headers show

Commit Message

Arnaud Charlet April 26, 2012, 9:46 a.m.
When front-end layout is enabled (such as for non-GCC targets like AAMP),
the RM_Size value of variant records with a static-sized single variant is
computed incorrectly as storage units rather than bits (which can cause
incorrect code for reading and writing objects). This case is now tested for
and RM_Size is properly determined as a bit size.

Tested on x86_64-pc-linux-gnu, committed on trunk

2012-04-26  Gary Dismukes  <dismukes@adacore.com>

	* layout.adb (Layout_Component_List): Test for the case of a
	single variant and the size of its component list was computed
	as an integer literal, and use that size (which is in bits)
	as is rather than converting to storage units.


Index: layout.adb
--- layout.adb	(revision 186860)
+++ layout.adb	(working copy)
@@ -6,7 +6,7 @@ 
 --                                                                          --
 --                                 B o d y                                  --
 --                                                                          --
---          Copyright (C) 2001-2011, Free Software Foundation, Inc.         --
+--          Copyright (C) 2001-2012, Free Software Foundation, Inc.         --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -2135,8 +2135,19 @@ 
                      --  others case.
                      if No (RM_Siz_Expr) then
-                        RM_Siz_Expr := Bits_To_SU (RM_SizV);
+                        --  If this is the only variant and the size is a
+                        --  literal, then use bit size as is, otherwise convert
+                        --  to storage units and continue to the next variant.
+                        if No (Prev (Var))
+                          and then Nkind (RM_SizV) = N_Integer_Literal
+                        then
+                           RM_Siz_Expr := RM_SizV;
+                        else
+                           RM_Siz_Expr := Bits_To_SU (RM_SizV);
+                        end if;
                      --  Otherwise construct the appropriate test