+2011-08-04 Eric Botcazou <ebotcazou@adacore.com>
+
+ * layout.adb (Layout_Type): For composite types, do not set Esize.
+ * freeze.adb (Set_Small_Size): Remove test on alignment and do not
+ set Esize.
+ (Size_Known): Look at the RM size of components instead of the Esize.
+ (Freeze_Record_Type): Look at the RM size instead of the Esize to
+ issue warning and activate Implicit_Packing.
+ (Freeze_Entity): Likewise. Do not issue a warning for alias/atomic
+ if the Esize is not known.
+ * sem_ch13.adb (Analyze_Attribute_Definition_Clause) <Size>: Set Esize
+ for elementary types only.
+ (Analyze_Record_Representation_Clause): Look at the RM size instead
+ of the Esize to issue errors.
+ * gcc-interface/decl.c (gnat_to_gnu_entity): Do not set Esize if it
+ is not known.
+ <E_Record_Type>: Look at the RM size instead of the Esize. Remove
+ obsolete block.
+ Look at the RM size instead of the Esize for types if the latter is
+ not known.
+ (gnat_to_gnu_field): Use Known_Esize instead of Known_Static_Esize.
+
+2011-08-04 Ed Schonberg <schonberg@adacore.com>
+
+ * sem_type.adb: proper handling of equality not involving anonymous
+ access types.
+
2011-08-04 Hristian Kirtchev <kirtchev@adacore.com>
* exp_ch7.adb (Create_Finalizer): Remove local variables Spec_Nod and
if S > 32 then
return;
- -- Don't bother if alignment clause with a value other than 1 is
- -- present, because size may be padded up to meet back end alignment
- -- requirements, and only the back end knows the rules!
-
- elsif Known_Alignment (T) and then Alignment (T) /= 1 then
- return;
-
-- Check for bad size clause given
elsif Has_Size_Clause (T) then
Error_Msg_NE
("size for& too small, minimum allowed is ^",
Size_Clause (T), T);
-
- elsif Unknown_Esize (T) then
- Set_Esize (T, S);
end if;
- -- Set sizes if not set already
-
- else
- if Unknown_Esize (T) then
- Set_Esize (T, S);
- end if;
+ -- Set size if not set already
- if Unknown_RM_Size (T) then
- Set_RM_Size (T, S);
- end if;
+ elsif Unknown_RM_Size (T) then
+ Set_RM_Size (T, S);
end if;
end Set_Small_Size;
if not Is_Constrained (T)
and then
No (Discriminant_Default_Value (First_Discriminant (T)))
- and then Unknown_Esize (T)
+ and then Unknown_RM_Size (T)
then
return False;
end if;
-- less than the sum of the object sizes (no point in packing if
-- this is not the case).
- and then Esize (Rec) < Scalar_Component_Total_Esize
+ and then RM_Size (Rec) < Scalar_Component_Total_Esize
-- And the total RM size cannot be greater than the specified size
-- since otherwise packing will not get us where we have to be!
- and then Esize (Rec) >= Scalar_Component_Total_RM_Size
+ and then RM_Size (Rec) >= Scalar_Component_Total_RM_Size
-- Never do implicit packing in CodePeer mode since we don't do
-- any packing in this mode, since this generates over-complex
-- action that causes stuff to be inherited).
if Present (Size_Clause (E))
- and then Known_Static_Esize (E)
+ and then Known_Static_RM_Size (E)
and then not Is_Packed (E)
and then not Has_Pragma_Pack (E)
and then Number_Dimensions (E) = 1
and then not Has_Component_Size_Clause (E)
- and then Known_Static_Esize (Ctyp)
+ and then Known_Static_RM_Size (Ctyp)
and then not Is_Limited_Composite (E)
and then not Is_Packed (Root_Type (E))
and then not Has_Component_Size_Clause (Root_Type (E))
-- Start of processing for Alias_Atomic_Check
begin
+
+ -- If object size of component type isn't known, we
+ -- cannot be sure so we defer to the back end.
+
+ if not Known_Static_Esize (Ctyp) then
+ null;
+
-- Case where component size has no effect. First
- -- check for object size of component type known
- -- and a multiple of the storage unit size.
+ -- check for object size of component type multiple
+ -- of the storage unit size.
- if Known_Static_Esize (Ctyp)
- and then Esize (Ctyp) mod System_Storage_Unit = 0
+ elsif Esize (Ctyp) mod System_Storage_Unit = 0
-- OK in both packing case and component size case
-- if RM size is known and static and the same as
if (esize > max_esize)
esize = max_esize;
}
- else
- esize = LONG_LONG_TYPE_SIZE;
}
switch (kind)
? -1
: (Known_Alignment (gnat_entity)
|| (Strict_Alignment (gnat_entity)
- && Known_Static_Esize (gnat_entity)))
+ && Known_RM_Size (gnat_entity)))
? -2
: 0;
bool has_discr = Has_Discriminants (gnat_entity);
/* If both a size and rep clause was specified, put the size in
the record type now so that it can get the proper mode. */
- if (has_rep && Known_Esize (gnat_entity))
- TYPE_SIZE (gnu_type) = UI_To_gnu (Esize (gnat_entity), sizetype);
+ if (has_rep && Known_RM_Size (gnat_entity))
+ TYPE_SIZE (gnu_type)
+ = UI_To_gnu (RM_Size (gnat_entity), bitsizetype);
/* Always set the alignment here so that it can be used to
set the mode, if it is making the alignment stricter. If
type size instead of the RM size (see validate_size). Cap the
alignment, lest it causes this type size to become too large. */
else if (Strict_Alignment (gnat_entity)
- && Known_Static_Esize (gnat_entity))
+ && Known_RM_Size (gnat_entity))
{
- unsigned int raw_size = UI_To_Int (Esize (gnat_entity));
+ unsigned int raw_size = UI_To_Int (RM_Size (gnat_entity));
unsigned int raw_align = raw_size & -raw_size;
if (raw_align < BIGGEST_ALIGNMENT)
TYPE_ALIGN (gnu_type) = raw_align;
confirming or we don't handle it properly (if the low bound is
non-constant). */
if (!gnu_size && kind != E_String_Literal_Subtype)
- gnu_size = validate_size (Esize (gnat_entity), gnu_type, gnat_entity,
- TYPE_DECL, false,
- Has_Size_Clause (gnat_entity));
+ {
+ Uint gnat_size = Known_Esize (gnat_entity)
+ ? Esize (gnat_entity) : RM_Size (gnat_entity);
+ gnu_size
+ = validate_size (gnat_size, gnu_type, gnat_entity, TYPE_DECL,
+ false, Has_Size_Clause (gnat_entity));
+ }
/* If a size was specified, see if we can make a new type of that size
by rearranging the type, for example from a fat to a thin pointer. */
/* If a size is specified, use it. Otherwise, if the record type is packed,
use the official RM size. See "Handling of Type'Size Values" in Einfo
for further details. */
- if (Known_Static_Esize (gnat_field))
+ if (Known_Esize (gnat_field))
gnu_size = validate_size (Esize (gnat_field), gnu_field_type,
gnat_field, FIELD_DECL, false, true);
else if (packed == 1)
end;
end if;
- -- If RM_Size is known, set Esize if not known
-
- if Known_RM_Size (E) and then Unknown_Esize (E) then
-
- -- If the alignment is known, we bump the Esize up to the next
- -- alignment boundary if it is not already on one.
-
- if Known_Alignment (E) then
- declare
- A : constant Uint := Alignment_In_Bits (E);
- S : constant SO_Ref := RM_Size (E);
- begin
- Set_Esize (E, (S + A - 1) / A * A);
- end;
- end if;
-
-- If Esize is set, and RM_Size is not, RM_Size is copied from Esize.
-- At least for now this seems reasonable, and is in any case needed
-- for compatibility with old versions of gigi.
- elsif Known_Esize (E) and then Unknown_RM_Size (E) then
+ if Known_Esize (E) and then Unknown_RM_Size (E) then
Set_RM_Size (E, Esize (E));
end if;
if Is_Type (U_Ent) then
Set_RM_Size (U_Ent, Size);
- -- For scalar types, increase Object_Size to power of 2, but
- -- not less than a storage unit in any case (i.e., normally
+ -- For elementary types, increase Object_Size to power of 2,
+ -- but not less than a storage unit in any case (normally
-- this means it will be byte addressable).
- if Is_Scalar_Type (U_Ent) then
+ -- For all other types, nothing else to do, we leave Esize
+ -- (object size) unset, the back end will set it from the
+ -- size and alignment in an appropriate manner.
+
+ if Is_Elementary_Type (U_Ent) then
if Size <= System_Storage_Unit then
Init_Esize (U_Ent, System_Storage_Unit);
elsif Size <= 16 then
Set_Esize (U_Ent, (Size + 63) / 64 * 64);
end if;
- -- For all other types, object size = value size. The
- -- backend will adjust as needed.
-
- else
- Set_Esize (U_Ent, Size);
+ Alignment_Check_For_Esize_Change (U_Ent);
end if;
- Alignment_Check_For_Esize_Change (U_Ent);
-
-- For objects, set Esize only
else
Lbit := Lbit + UI_From_Int (SSU) * Posit;
if Has_Size_Clause (Rectype)
- and then Esize (Rectype) <= Lbit
+ and then RM_Size (Rectype) <= Lbit
then
Error_Msg_N
("bit number out of range of specified size",
-- Check bit position out of range of specified size
if Has_Size_Clause (Rectype)
- and then Esize (Rectype) <= Lbit
+ and then RM_Size (Rectype) <= Lbit
then
Error_Msg_N
("bit number out of range of specified size",
-- Look for exact type match in an instance, to remove spurious
-- ambiguities when two formal types have the same actual.
+ function Operand_Type return Entity_Id;
+ -- Determine type of operand for an equality operation, to apply
+ -- Ada2005 rules to equality on anonymous access types.
+
function Standard_Operator return Boolean;
-- Check whether subprogram is predefined operator declared in Standard.
-- It may given by an operator name, or by an expanded name whose prefix
and then (T1 = Universal_Real or else T1 = Universal_Integer));
end Matches;
+ ------------------
+ -- Operand_Type --
+ ------------------
+
+ function Operand_Type return Entity_Id is
+ Opnd : Node_Id;
+ begin
+ if Nkind (N) = N_Function_Call then
+ Opnd := First_Actual (N);
+ else
+ Opnd := Left_Opnd (N);
+ end if;
+ return Etype (Opnd);
+
+ end Operand_Type;
+
------------------------
-- Remove_Conversions --
------------------------
-- may be an operator or a function call.
elsif (Chars (Nam1) = Name_Op_Eq
- or else
- Chars (Nam1) = Name_Op_Ne)
+ or else
+ Chars (Nam1) = Name_Op_Ne)
and then Ada_Version >= Ada_2005
and then Etype (User_Subp) = Standard_Boolean
- then
- declare
- Opnd : Node_Id;
-
- begin
- if Nkind (N) = N_Function_Call then
- Opnd := First_Actual (N);
- else
- Opnd := Left_Opnd (N);
- end if;
-
- if Ekind (Etype (Opnd)) = E_Anonymous_Access_Type
- and then
- In_Same_List (Parent (Designated_Type (Etype (Opnd))),
+ and then Ekind (Operand_Type) = E_Anonymous_Access_Type
+ and then
+ In_Same_List (Parent (Designated_Type (Operand_Type)),
Unit_Declaration_Node (User_Subp))
- then
- if It2.Nam = Predef_Subp then
- return It1;
- else
- return It2;
- end if;
- else
- return Remove_Conversions;
- end if;
- end;
+ then
+ if It2.Nam = Predef_Subp then
+ return It1;
+ else
+ return It2;
+ end if;
-- An immediately visible operator hides a use-visible user-
-- defined operation. This disambiguation cannot take place