Atomic or Volatile components must occupy their "natural" size and position
in records, with allocated room and alignment matching what the component type
calls for in absence of a rep clause for the component.
There was a dissimetry in the gigi code checking for this, with
- the checks on position featuring a single case for volatile covering
atomic as well, and a gcc_unreachable() at the end.
- the checks on size featuring a case for atomic only, missing the
lone-volatile case and not having a gcc_unreachable() at the end.
The change introduced here improves this code to have the size
and position checks match each other, adding the missing case and
the gcc_unreachable() to the size checks, and splitting the volatile
case into two more precise checks for position.
Tested on x86_64-suse-linux, applied on mainline.
2013-01-06 Olivier Hainque <hain...@adacore.com>
* gcc-interface/decl.c (gnat_to_gnu_field): Emit a specialized
diagnostic for component size mismatch wrt volatile requirements.
Add a gcc_unreachable() at the end of the checks for size. Split
the check on volatile for positions into one check on atomic and
a subsequent one on volatile.
2013-01-06 Olivier Hainque <hain...@adacore.com>
* gnat.dg/specs/clause_on_volatile.ads: New test.
--
Eric Botcazou
Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c (revision 194945)
+++ gcc-interface/decl.c (working copy)
@@ -6489,10 +6489,11 @@ gnat_to_gnu_field (Entity_Id gnat_field,
}
/* If this field needs strict alignment, check that the record is
- sufficiently aligned and that position and size are consistent
- with the alignment. But don't do it if we are just annotating
- types and the field's type is tagged, since tagged types aren't
- fully laid out in this mode. */
+ sufficiently aligned and that position and size are consistent with
+ the alignment. But don't do it if we are just annotating types and
+ the field's type is tagged, since tagged types aren't fully laid out
+ in this mode. Also, note that atomic implies volatile so the inner
+ test sequences ordering is significant here. */
if (needs_strict_alignment
&& !(type_annotate_only && Is_Tagged_Type (gnat_field_type)))
{
@@ -6508,6 +6509,12 @@ gnat_to_gnu_field (Entity_Id gnat_field,
Last_Bit (Component_Clause (gnat_field)), gnat_field,
TYPE_SIZE (gnu_field_type));
+ else if (is_volatile)
+ post_error_ne_tree
+ ("volatile field& must be natural size of type{ (^)}",
+ Last_Bit (Component_Clause (gnat_field)), gnat_field,
+ TYPE_SIZE (gnu_field_type));
+
else if (Is_Aliased (gnat_field))
post_error_ne_tree
("size of aliased field& must be ^ bits",
@@ -6520,6 +6527,9 @@ gnat_to_gnu_field (Entity_Id gnat_field,
Last_Bit (Component_Clause (gnat_field)), gnat_field,
TYPE_SIZE (gnu_field_type));
+ else
+ gcc_unreachable ();
+
gnu_size = NULL_TREE;
}
@@ -6527,7 +6537,13 @@ gnat_to_gnu_field (Entity_Id gnat_field,
(TRUNC_MOD_EXPR, gnu_pos,
bitsize_int (TYPE_ALIGN (gnu_field_type)))))
{
- if (is_volatile)
+ if (Is_Atomic (gnat_field) || Is_Atomic (gnat_field_type))
+ post_error_ne_num
+ ("position of atomic field& must be multiple of ^ bits",
+ First_Bit (Component_Clause (gnat_field)), gnat_field,
+ TYPE_ALIGN (gnu_field_type));
+
+ else if (is_volatile)
post_error_ne_num
("position of volatile field& must be multiple of ^ bits",
First_Bit (Component_Clause (gnat_field)), gnat_field,
-- { dg-do compile }
package Clause_On_Volatile is
type U8 is mod 2 ** 8;
type Word is record
A, B : U8;
end record;
For Word'Alignment use 4;
type Vword is new Word;
For Vword'Alignment use 4;
pragma Volatile (Vword);
type Aword is new Word;
For Aword'Alignment use 4;
pragma Atomic (Aword);
type R1 is record
W : Word;
end record;
for R1 use record
W at 0 range 0 .. 15; -- OK, packing regular
end record;
type A1 is record
AW : Aword;
end record;
For A1'Alignment use 4;
for A1 use record
AW at 0 range 0 .. 15; -- { dg-error "must be natural size" }
end record;
type A2 is record
B : U8;
AW : Aword;
end record;
For A2'Alignment use 4;
for A2 use record
B at 0 range 0 .. 7;
AW at 1 range 0 .. 31; -- { dg-error "must be multiple" }
end record;
type A3 is record
B : U8;
AW : Aword;
end record;
For A3'Alignment use 4;
for A3 use record
B at 0 range 0 .. 7;
AW at 1 range 0 .. 15; -- { dg-error "must be (multiple|natural size)" }
end record;
--
type V1 is record
VW : Vword;
end record;
For V1'Alignment use 4;
for V1 use record
VW at 0 range 0 .. 15; -- { dg-error "must be natural size" }
end record;
type V2 is record
B : U8;
VW : Vword;
end record;
For V2'Alignment use 4;
for V2 use record
B at 0 range 0 .. 7;
VW at 1 range 0 .. 31; -- { dg-error "must be multiple" }
end record;
type V3 is record
B : U8;
VW : Vword;
end record;
For V3'Alignment use 4;
for V3 use record
B at 0 range 0 .. 7;
VW at 1 range 0 .. 15; -- { dg-error "must be (multiple|natural size)" }
end record;
end Clause_On_Volatile;