aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/exp_util.adb
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2004-06-28 16:37:05 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2004-06-28 16:37:05 +0200
commit246d2ceb324bb3483062b211a262aa290f5ecf41 (patch)
treec84a063a47e404a2c3fd2bf0942d1e94a944cbfe /gcc/ada/exp_util.adb
parent45da19e38e9b2fecb8c4c609ba2b99be9dcc84ae (diff)
downloadgcc-246d2ceb324bb3483062b211a262aa290f5ecf41.zip
gcc-246d2ceb324bb3483062b211a262aa290f5ecf41.tar.gz
gcc-246d2ceb324bb3483062b211a262aa290f5ecf41.tar.bz2
[multiple changes]
2004-06-28 Robert Dewar <dewar@gnat.com> * mlib-tgt-tru64.adb, mlib-tgt-aix.adb, mlib-tgt-irix.adb, mlib-tgt-irix.adb, mlib-tgt-hpux.adb, mlib-tgt-linux.adb, mlib-tgt-linux.adb, mlib-tgt-solaris.adb, mlib-tgt-solaris.adb, mlib-tgt-vms-alpha.adb, mlib-tgt-vms-alpha.adb, mlib-tgt-vms-ia64.adb, a-strmap.adb, a-strmap.ads, clean.adb: Minor reformatting * exp_util.adb (Is_Possibly_Unaligned_Slice): Completely rewritten, to deal with problem of inefficient slices on machines with strict alignment, when the slice is a component of a composite. * checks.adb (Apply_Array_Size_Check): Do not special case 64-bit machines, we need the check there as well. 2004-06-28 Ed Schonberg <schonberg@gnat.com> * exp_ch5.adb (Expand_Assign_Array): Use correct condition to determine safe copying direction for overlapping slice assignments when component is controlled. * sem_ch12.adb (Instantiate_Formal_Package): Implicit operations of a formal derived type in the actual for a formal package are visible in the enclosing instance. 2004-06-28 Ed Schonberg <schonberg@gnat.com> PR ada/15600 * sem_util.adb (Trace_Components): Diagnose properly an illegal circularity involving a private type whose completion includes a self-referential component. (Enter_Name): Use Is_Inherited_Operation to distinguish a source renaming or an instantiation from an implicit derived operation. 2004-06-28 Pascal Obry <obry@gnat.com> * mlib-tgt-mingw.adb: (Library_Exists_For): Remove "lib" prefix from DLL. (Library_File_Name_For): Idem. 2004-06-28 Matthew Gingell <gingell@gnat.com> * g-traceb.ads: Add explanatory note on the format of addresses expected by addr2line. 2004-06-28 Jerome Guitton <guitton@act-europe.fr> * Makefile.in: Force debugging information on s-tasdeb.adb, a-except.adb and s-assert.adb needed by the debugger. 2004-06-28 Vincent Celier <celier@gnat.com> * make.adb (Collect_Arguments_And_Compile): Change Flag1 to Need_To_Build_Lib. (Gnatmake): Ditto. * mlib-prj.adb (Check_Library): Replace Flag1 with Need_To_Build_Lib * prj.adb: Minor reformatting (Project_Empty): Change Flag1 to Need_To_Build_Lib. Remove Flag2. * prj.ads: Comment updates Minor reformatting (Project_Data): Change Flag1 to Need_To_Build_Lib. Remove Flag2: not used. * prj-dect.adb (Parse_Declarative_Items): Accept "null" as a declaration. * gnat_ugn.texi: Put a "null;" declaration in one project file example * gnat_rm.texi: Document Empty declarations "null;". * makegpr.adb (Compile_Link_With_Gnatmake): Put the global archives in front of the linker options. (Link_Foreign): Put the global archives and the libraries in front of the linker options. 2004-06-28 Javier Miranda <miranda@gnat.com> * rtsfind.adb: (Get_Unit_Name): Fix typo in comment (RTU_Loaded): Code cleanup (Set_RTU_Loaded): New procedure to register as *loaded* explicitly withed predefined units. * rtsfind.ads (Set_RTU_Loaded): New procedure to register as *loaded* explicitly withed predefined units. Fix typo in comment * sem_ch10.adb (Analyze_Compilation_Unit): Register as *loaded* explicitly withed predefined units. From-SVN: r83789
Diffstat (limited to 'gcc/ada/exp_util.adb')
-rw-r--r--gcc/ada/exp_util.adb166
1 files changed, 102 insertions, 64 deletions
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index e90c491..9e1a7ec1 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -2384,34 +2384,6 @@ package body Exp_Util is
---------------------------------
function Is_Possibly_Unaligned_Slice (P : Node_Id) return Boolean is
-
- function Has_Non_Trivial_Component_Clause (E : Entity_Id) return Boolean;
- -- Check whether the component clause might place the component at an
- -- alignment that will require the use of a copy when a slice is passed
- -- as a parameter. The code is conservative because at this point the
- -- expander does not know the alignment choice that the back-end will
- -- make. For now we return true if the component is not the first one
- -- in the enclosing record. This routine is a place holder for further
- -- analysis of this kind.
-
- --------------------------------------
- -- Has_Non_Trivial_Component_Clause --
- --------------------------------------
-
- function Has_Non_Trivial_Component_Clause (E : Entity_Id) return Boolean
- is
- Rep_Clause : constant Node_Id := Component_Clause (E);
- begin
- if No (Rep_Clause) then
- return False;
- else
- return Intval (Position (Rep_Clause)) /= Uint_0
- or else Intval (First_Bit (Rep_Clause)) /= Uint_0;
- end if;
- end Has_Non_Trivial_Component_Clause;
-
- -- Start of processing for Is_Possibly_Unaligned_Slice
-
begin
-- ??? GCC3 will eventually handle strings with arbitrary alignments,
-- but for now the following check must be disabled.
@@ -2420,6 +2392,8 @@ package body Exp_Util is
-- return False;
-- end if;
+ -- For renaming case, go to renamed object
+
if Is_Entity_Name (P)
and then Is_Object (Entity (P))
and then Present (Renamed_Object (Entity (P)))
@@ -2427,57 +2401,121 @@ package body Exp_Util is
return Is_Possibly_Unaligned_Slice (Renamed_Object (Entity (P)));
end if;
- -- We only need to worry if the target has strict alignment, unless
- -- it is a nested record component with a component clause, which
- -- Gigi does not handle well. This patch should disappear with GCC 3.0
- -- and it is not clear why it is needed even when the representation
- -- clause is a confirming one, but in its absence gigi complains that
- -- the slice is not addressable.???
+ -- The reference must be a slice
- if not Target_Strict_Alignment then
- if Nkind (P) /= N_Slice
- or else Nkind (Prefix (P)) /= N_Selected_Component
- or else Nkind (Prefix (Prefix (P))) /= N_Selected_Component
- then
- return False;
- end if;
+ if Nkind (P) /= N_Slice then
+ return False;
end if;
- -- The reference must be a slice
+ -- Always assume the worst for a nested record component with a
+ -- component clause, which gigi/gcc does not appear to handle well.
+ -- It is not clear why this special test is needed at all ???
- if Nkind (P) /= N_Slice then
+ if Nkind (Prefix (P)) = N_Selected_Component
+ and then Nkind (Prefix (Prefix (P))) = N_Selected_Component
+ and then
+ Present (Component_Clause (Entity (Selector_Name (Prefix (P)))))
+ then
+ return True;
+ end if;
+
+ -- We only need to worry if the target has strict alignment
+
+ if not Target_Strict_Alignment then
return False;
end if;
-- If it is a slice, then look at the array type being sliced
declare
- Pref : constant Node_Id := Prefix (P);
- Typ : constant Entity_Id := Etype (Prefix (P));
+ Sarr : constant Node_Id := Prefix (P);
+ -- Prefix of the slice, i.e. the array being sliced
+
+ Styp : constant Entity_Id := Etype (Prefix (P));
+ -- Type of the array being sliced
+
+ Pref : Node_Id;
+ Ptyp : Entity_Id;
begin
- -- The worrisome case is one where we don't know the alignment
- -- of the array, or we know it and it is greater than 1 (if the
- -- alignment is one, then obviously it cannot be misaligned).
+ -- The problems arise if the array object that is being sliced
+ -- is a component of a record or array, and we cannot guarantee
+ -- the alignment of the array within its containing object.
- if Known_Alignment (Typ) and then Alignment (Typ) = 1 then
- return False;
- end if;
+ -- To investigate this, we look at successive prefixes to see
+ -- if we have a worrisome indexed or selected component.
- -- The only way we can be unaligned is if the array being sliced
- -- is a component of a record, and either the record is packed,
- -- or the component has a component clause, or the record has
- -- a specified alignment (that might be too small).
+ Pref := Sarr;
+ loop
+ -- Case of array is part of an indexed component reference
- return
- Nkind (Pref) = N_Selected_Component
- and then
- (Is_Packed (Etype (Prefix (Pref)))
- or else
- Known_Alignment (Etype (Prefix (Pref)))
- or else
- Has_Non_Trivial_Component_Clause
- (Entity (Selector_Name (Pref))));
+ if Nkind (Pref) = N_Indexed_Component then
+ Ptyp := Etype (Prefix (Pref));
+
+ -- The only problematic case is when the array is packed,
+ -- in which case we really know nothing about the alignment
+ -- of individual components.
+
+ if Is_Bit_Packed_Array (Ptyp) then
+ return True;
+ end if;
+
+ -- Case of array is part of a selected component reference
+
+ elsif Nkind (Pref) = N_Selected_Component then
+ Ptyp := Etype (Prefix (Pref));
+
+ -- We are definitely in trouble if the record in question
+ -- has an alignment, and either we know this alignment is
+ -- inconsistent with the alignment of the slice, or we
+ -- don't know what the alignment of the slice should be.
+
+ if Known_Alignment (Ptyp)
+ and then (Unknown_Alignment (Styp)
+ or else Alignment (Styp) > Alignment (Ptyp))
+ then
+ return True;
+ end if;
+
+ -- We are in potential trouble if the record type is packed.
+ -- We could special case when we know that the array is the
+ -- first component, but that's not such a simple case ???
+
+ if Is_Packed (Ptyp) then
+ return True;
+ end if;
+
+ -- We are in trouble if there is a component clause, and
+ -- either we do not know the alignment of the slice, or
+ -- the alignment of the slice is inconsistent with the
+ -- bit position specified by the component clause.
+
+ declare
+ Field : constant Entity_Id := Entity (Selector_Name (Pref));
+ begin
+ if Present (Component_Clause (Field))
+ and then
+ (Unknown_Alignment (Styp)
+ or else
+ (Component_Bit_Offset (Field) mod
+ (System_Storage_Unit * Alignment (Styp))) /= 0)
+ then
+ return True;
+ end if;
+ end;
+
+ -- For cases other than selected or indexed components we
+ -- know we are OK, since no issues arise over alignment.
+
+ else
+ return False;
+ end if;
+
+ -- We processed an indexed component or selected component
+ -- reference that looked safe, so keep checking prefixes.
+
+ Pref := Prefix (Pref);
+ end loop;
end;
end Is_Possibly_Unaligned_Slice;