diff options
author | Arnaud Charlet <charlet@gcc.gnu.org> | 2004-06-28 16:37:05 +0200 |
---|---|---|
committer | Arnaud Charlet <charlet@gcc.gnu.org> | 2004-06-28 16:37:05 +0200 |
commit | 246d2ceb324bb3483062b211a262aa290f5ecf41 (patch) | |
tree | c84a063a47e404a2c3fd2bf0942d1e94a944cbfe /gcc/ada/exp_util.adb | |
parent | 45da19e38e9b2fecb8c4c609ba2b99be9dcc84ae (diff) | |
download | gcc-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.adb | 166 |
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; |