Commit 35786aad by Eric Botcazou Committed by Eric Botcazou

decl.c (gnat_to_gnu_field): Post the error message for parent overlapping on the…

decl.c (gnat_to_gnu_field): Post the error message for parent overlapping on the position instead of on the...

	* gcc-interface/decl.c (gnat_to_gnu_field): Post the error message
	for parent overlapping on the position instead of on the first bit.
	For a field that needs strict alignment, issue the error for the
	position first and, for the size, issue an error if it is too large
	only for the atomic and aliased cases.  Issue a specific error if
	the size is not a multiple of a byte in the volatile and the stric
	alignment cases.

From-SVN: r219009
parent ae9f4345
2014-12-22 Eric Botcazou <ebotcazou@adacore.com> 2014-12-22 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (gnat_to_gnu_field): Post the error message
for parent overlapping on the position instead of on the first bit.
For a field that needs strict alignment, issue the error for the
position first and, for the size, issue an error if it is too large
only for the atomic and aliased cases. Issue a specific error if
the size is not a multiple of a byte in the volatile and the stric
alignment cases.
2014-12-22 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (check_ok_for_atomic): Rename into... * gcc-interface/decl.c (check_ok_for_atomic): Rename into...
(check_ok_for_atomic_type): ...this. When checking the mode, also (check_ok_for_atomic_type): ...this. When checking the mode, also
check that the type is sufficient aligned. Remove useless code and check that the type is sufficient aligned. Remove useless code and
......
...@@ -6414,12 +6414,14 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed, ...@@ -6414,12 +6414,14 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
tree gnu_field_type = gnat_to_gnu_type (gnat_field_type); tree gnu_field_type = gnat_to_gnu_type (gnat_field_type);
tree gnu_field_id = get_entity_name (gnat_field); tree gnu_field_id = get_entity_name (gnat_field);
tree gnu_field, gnu_size, gnu_pos; tree gnu_field, gnu_size, gnu_pos;
bool is_aliased
= Is_Aliased (gnat_field);
bool is_atomic
= (Is_Atomic (gnat_field) || Is_Atomic (gnat_field_type));
bool is_volatile bool is_volatile
= (Treat_As_Volatile (gnat_field) || Treat_As_Volatile (gnat_field_type)); = (Treat_As_Volatile (gnat_field) || Treat_As_Volatile (gnat_field_type));
bool needs_strict_alignment bool needs_strict_alignment
= (is_volatile = (is_aliased || is_volatile || Strict_Alignment (gnat_field_type));
|| Is_Aliased (gnat_field)
|| Strict_Alignment (gnat_field_type));
/* If this field requires strict alignment, we cannot pack it because /* If this field requires strict alignment, we cannot pack it because
it would very likely be under-aligned in the record. */ it would very likely be under-aligned in the record. */
...@@ -6488,6 +6490,7 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed, ...@@ -6488,6 +6490,7 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
if (Present (Component_Clause (gnat_field))) if (Present (Component_Clause (gnat_field)))
{ {
Node_Id gnat_clause = Component_Clause (gnat_field);
Entity_Id gnat_parent Entity_Id gnat_parent
= Parent_Subtype (Underlying_Type (Scope (gnat_field))); = Parent_Subtype (Underlying_Type (Scope (gnat_field)));
...@@ -6506,91 +6509,95 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed, ...@@ -6506,91 +6509,95 @@ gnat_to_gnu_field (Entity_Id gnat_field, tree gnu_record_type, int packed,
if (TREE_CODE (TYPE_SIZE (gnu_parent)) == INTEGER_CST if (TREE_CODE (TYPE_SIZE (gnu_parent)) == INTEGER_CST
&& tree_int_cst_lt (gnu_pos, TYPE_SIZE (gnu_parent))) && tree_int_cst_lt (gnu_pos, TYPE_SIZE (gnu_parent)))
{ post_error_ne_tree
post_error_ne_tree ("offset of& must be beyond parent{, minimum allowed is ^}",
("offset of& must be beyond parent{, minimum allowed is ^}", Position (gnat_clause), gnat_field, TYPE_SIZE_UNIT (gnu_parent));
First_Bit (Component_Clause (gnat_field)), gnat_field,
TYPE_SIZE_UNIT (gnu_parent));
}
} }
/* If this field needs strict alignment, check that the record is /* If this field needs strict alignment, make sure that the record is
sufficiently aligned and that position and size are consistent with sufficiently aligned and that the position and size are consistent
the alignment. But don't do it if we are just annotating types and with the type. 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 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 in this mode. Also, note that atomic implies volatile so the inner
test sequences ordering is significant here. */ test sequences ordering is significant here. */
if (needs_strict_alignment if (needs_strict_alignment
&& !(type_annotate_only && Is_Tagged_Type (gnat_field_type))) && !(type_annotate_only && Is_Tagged_Type (gnat_field_type)))
{ {
TYPE_ALIGN (gnu_record_type) const unsigned int type_align = TYPE_ALIGN (gnu_field_type);
= MAX (TYPE_ALIGN (gnu_record_type), TYPE_ALIGN (gnu_field_type));
if (TYPE_ALIGN (gnu_record_type) < type_align)
TYPE_ALIGN (gnu_record_type) = type_align;
if (gnu_size /* If the position is not a multiple of the alignment of the type,
&& !operand_equal_p (gnu_size, TYPE_SIZE (gnu_field_type), 0)) then error out and reset the position. */
if (!integer_zerop (size_binop (TRUNC_MOD_EXPR, gnu_pos,
bitsize_int (type_align))))
{ {
if (Is_Atomic (gnat_field) || Is_Atomic (gnat_field_type)) const char *s;
post_error_ne_tree
("atomic field& must be natural size of type{ (^)}",
Last_Bit (Component_Clause (gnat_field)), gnat_field,
TYPE_SIZE (gnu_field_type));
if (is_atomic)
s = "position of atomic field& must be multiple of ^ bits";
else if (is_aliased)
s = "position of aliased field& must be multiple of ^ bits";
else if (is_volatile) else if (is_volatile)
post_error_ne_tree s = "position of volatile field& must be multiple of ^ bits";
("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",
Last_Bit (Component_Clause (gnat_field)), gnat_field,
TYPE_SIZE (gnu_field_type));
else if (Strict_Alignment (gnat_field_type)) else if (Strict_Alignment (gnat_field_type))
post_error_ne_tree s = "position of & with aliased or tagged part must be"
("size of & with aliased or tagged components not ^ bits", " multiple of ^ bits";
Last_Bit (Component_Clause (gnat_field)), gnat_field, else
TYPE_SIZE (gnu_field_type));
else
gcc_unreachable (); gcc_unreachable ();
gnu_size = NULL_TREE; post_error_ne_num (s, First_Bit (gnat_clause), gnat_field,
type_align);
gnu_pos = NULL_TREE;
} }
if (!integer_zerop (size_binop if (gnu_size)
(TRUNC_MOD_EXPR, gnu_pos,
bitsize_int (TYPE_ALIGN (gnu_field_type)))))
{ {
if (Is_Atomic (gnat_field) || Is_Atomic (gnat_field_type)) tree gnu_type_size = TYPE_SIZE (gnu_field_type);
post_error_ne_num const int cmp = tree_int_cst_compare (gnu_size, gnu_type_size);
("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,
TYPE_ALIGN (gnu_field_type));
else if (Is_Aliased (gnat_field))
post_error_ne_num
("position of aliased field& must be multiple of ^ bits",
First_Bit (Component_Clause (gnat_field)), gnat_field,
TYPE_ALIGN (gnu_field_type));
else if (Strict_Alignment (gnat_field_type)) /* If the size is lower than that of the type, or greater for
post_error_ne atomic and aliased, then error out and reset the size. */
("position of & is not compatible with alignment required " if (cmp < 0 || (cmp > 0 && (is_atomic || is_aliased)))
"by its components", {
First_Bit (Component_Clause (gnat_field)), gnat_field); const char *s;
if (is_atomic)
s = "size of atomic field& must be ^ bits";
else if (is_aliased)
s = "size of aliased field& must be ^ bits";
else if (is_volatile)
s = "size of volatile field& must be at least ^ bits";
else if (Strict_Alignment (gnat_field_type))
s = "size of & with aliased or tagged part must be"
" at least ^ bits";
else
gcc_unreachable ();
else post_error_ne_tree (s, Last_Bit (gnat_clause), gnat_field,
gcc_unreachable (); gnu_type_size);
gnu_size = NULL_TREE;
}
gnu_pos = NULL_TREE; /* Likewise if the size is not a multiple of a byte, */
else if (!integer_zerop (size_binop (TRUNC_MOD_EXPR, gnu_size,
bitsize_unit_node)))
{
const char *s;
if (is_volatile)
s = "size of volatile field& must be multiple of"
" Storage_Unit";
else if (Strict_Alignment (gnat_field_type))
s = "size of & with aliased or tagged part must be"
" multiple of Storage_Unit";
else
gcc_unreachable ();
post_error_ne (s, Last_Bit (gnat_clause), gnat_field);
gnu_size = NULL_TREE;
}
} }
} }
} }
......
2014-12-22 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/specs/volatile1.ads: New test.
* gnat.dg/specs/clause_on_volatile.ads: Adjust.
* gnat.dg/specs/size_clause3.ads: Likewise.
2014-12-22 Bin Cheng <bin.cheng@arm.com> 2014-12-22 Bin Cheng <bin.cheng@arm.com>
PR rtl-optimization/62151 PR rtl-optimization/62151
......
...@@ -21,7 +21,7 @@ package Clause_On_Volatile is ...@@ -21,7 +21,7 @@ package Clause_On_Volatile is
W : Word; W : Word;
end record; end record;
for R1 use record for R1 use record
W at 0 range 0 .. 15; -- OK, packing regular W at 0 range 0 .. 15; -- OK
end record; end record;
type A1 is record type A1 is record
...@@ -29,7 +29,7 @@ package Clause_On_Volatile is ...@@ -29,7 +29,7 @@ package Clause_On_Volatile is
end record; end record;
For A1'Alignment use 4; For A1'Alignment use 4;
for A1 use record for A1 use record
AW at 0 range 0 .. 15; -- { dg-error "must be natural size" } AW at 0 range 0 .. 15; -- { dg-error "must be \[0-9\]*" }
end record; end record;
type A2 is record type A2 is record
...@@ -49,17 +49,15 @@ package Clause_On_Volatile is ...@@ -49,17 +49,15 @@ package Clause_On_Volatile is
For A3'Alignment use 4; For A3'Alignment use 4;
for A3 use record for A3 use record
B at 0 range 0 .. 7; B at 0 range 0 .. 7;
AW at 1 range 0 .. 15; -- { dg-error "must be (multiple|natural size)" } AW at 1 range 0 .. 15; -- { dg-error "must be (multiple||\[0-9\]*)" }
end record; end record;
--
type V1 is record type V1 is record
VW : Vword; VW : Vword;
end record; end record;
For V1'Alignment use 4; For V1'Alignment use 4;
for V1 use record for V1 use record
VW at 0 range 0 .. 15; -- { dg-error "must be natural size" } VW at 0 range 0 .. 15; -- { dg-error "must be at least" }
end record; end record;
type V2 is record type V2 is record
...@@ -79,7 +77,7 @@ package Clause_On_Volatile is ...@@ -79,7 +77,7 @@ package Clause_On_Volatile is
For V3'Alignment use 4; For V3'Alignment use 4;
for V3 use record for V3 use record
B at 0 range 0 .. 7; B at 0 range 0 .. 7;
VW at 1 range 0 .. 15; -- { dg-error "must be (multiple|natural size)" } VW at 1 range 0 .. 15; -- { dg-error "must be (multiple|at least)" }
end record; end record;
end Clause_On_Volatile; end Clause_On_Volatile;
...@@ -14,7 +14,7 @@ package Size_Clause3 is ...@@ -14,7 +14,7 @@ package Size_Clause3 is
rr : R1; -- size must be 40 rr : R1; -- size must be 40
end record; end record;
for S1 use record for S1 use record
rr at 0 range 0 .. 39; -- { dg-error "size of .rr. with aliased or tagged component" } rr at 0 range 0 .. 39; -- { dg-error "size of .rr. with aliased or tagged" }
end record; end record;
-- The record is explicitly given alignment 1 so its real type is 40. -- The record is explicitly given alignment 1 so its real type is 40.
...@@ -44,7 +44,7 @@ package Size_Clause3 is ...@@ -44,7 +44,7 @@ package Size_Clause3 is
rr : R3; -- size must be 40 rr : R3; -- size must be 40
end record; end record;
for S3 use record for S3 use record
rr at 0 range 0 .. 39; -- { dg-error "size of .rr. with aliased or tagged component" } rr at 0 range 0 .. 39; -- { dg-error "size of .rr. with aliased or tagged" }
end record; end record;
end Size_Clause3; end Size_Clause3;
-- { dg-do compile }
package Volatile1 is
C : Character;
for C'Size use 32;
pragma Volatile (C);
type R1 is record
C: Character;
pragma Volatile (C);
end record;
for R1 use record
C at 0 range 0 .. 31;
end record;
type R2 is record
C: Character;
pragma Volatile (C);
end record;
for R2 use record
C at 0 range 0 .. 10; -- { dg-error "size of volatile field" }
end record;
end Volatile1;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment