aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
authorArnaud Charlet <charlet@gcc.gnu.org>2016-05-02 12:34:16 +0200
committerArnaud Charlet <charlet@gcc.gnu.org>2016-05-02 12:34:16 +0200
commitfc3819c9b4924ae0cc0e19826ba27afd4a46f169 (patch)
treefd24ec6706d1850fce6ff19dacedc77549e9d96f /gcc/ada
parent494a7e453377c5a99277c217005685203b07615b (diff)
downloadgcc-fc3819c9b4924ae0cc0e19826ba27afd4a46f169.zip
gcc-fc3819c9b4924ae0cc0e19826ba27afd4a46f169.tar.gz
gcc-fc3819c9b4924ae0cc0e19826ba27afd4a46f169.tar.bz2
[multiple changes]
2016-05-02 Ed Schonberg <schonberg@adacore.com> * exp_ch6.adb (Expand_Call): When inlining a call to a function declared in a package instance, locate the instance node of the package after the actual package declaration. skipping over pragmas that may have been introduced when the generic unit carries aspects that are transformed into pragmas. 2016-05-02 Bob Duff <duff@adacore.com> * s-memory.adb (Alloc, Realloc): Move checks for Size = 0 or size_t'Last into the Result = System.Null_Address path for efficiency. Improve comments (based on actual C language requirements for malloc). * exp_util.adb (Build_Allocate_Deallocate_Proc): Optimize the case where we are using the default Global_Pool_Object, and we don't need the heavy finalization machinery. From-SVN: r235745
Diffstat (limited to 'gcc/ada')
-rw-r--r--gcc/ada/ChangeLog18
-rw-r--r--gcc/ada/exp_ch6.adb19
-rw-r--r--gcc/ada/exp_util.adb8
-rw-r--r--gcc/ada/s-memory.adb70
4 files changed, 79 insertions, 36 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 2a0ef8d..8764dbb 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,3 +1,21 @@
+2016-05-02 Ed Schonberg <schonberg@adacore.com>
+
+ * exp_ch6.adb (Expand_Call): When inlining a call to a function
+ declared in a package instance, locate the instance node of the
+ package after the actual package declaration. skipping over
+ pragmas that may have been introduced when the generic unit
+ carries aspects that are transformed into pragmas.
+
+2016-05-02 Bob Duff <duff@adacore.com>
+
+ * s-memory.adb (Alloc, Realloc): Move checks
+ for Size = 0 or size_t'Last into the Result = System.Null_Address
+ path for efficiency. Improve comments (based on actual C language
+ requirements for malloc).
+ * exp_util.adb (Build_Allocate_Deallocate_Proc): Optimize the
+ case where we are using the default Global_Pool_Object, and we
+ don't need the heavy finalization machinery.
+
2016-05-02 Gary Dismukes <dismukes@adacore.com>
* exp_util.ads, sem_ch12.adb: Minor reformatting.
diff --git a/gcc/ada/exp_ch6.adb b/gcc/ada/exp_ch6.adb
index 4c89374..aff75ac 100644
--- a/gcc/ada/exp_ch6.adb
+++ b/gcc/ada/exp_ch6.adb
@@ -3970,8 +3970,9 @@ package body Exp_Ch6 is
and then Optimization_Level > 0
then
declare
- Inst : Entity_Id;
- Decl : Node_Id;
+ Decl : Node_Id;
+ Inst : Entity_Id;
+ Inst_Node : Node_Id;
begin
Inst := Scope (Subp);
@@ -4001,7 +4002,19 @@ package body Exp_Ch6 is
null;
else
- Add_Pending_Instantiation (Next (Decl), Decl);
+ -- The instantiation node follows the package
+ -- declaration for the instance. If the generic
+ -- unit had aspect specifications, they have
+ -- been transformed into pragmas in the instance,
+ -- and the instance node appears after them.
+
+ Inst_Node := Next (Decl);
+
+ while Nkind (Inst_Node) /= N_Package_Instantiation loop
+ Inst_Node := Next (Inst_Node);
+ end loop;
+
+ Add_Pending_Instantiation (Inst_Node, Decl);
end if;
end if;
end;
diff --git a/gcc/ada/exp_util.adb b/gcc/ada/exp_util.adb
index 011ccc4..4ea4cb2 100644
--- a/gcc/ada/exp_util.adb
+++ b/gcc/ada/exp_util.adb
@@ -584,6 +584,14 @@ package body Exp_Util is
elsif Is_RTE (Pool_Id, RE_SS_Pool) then
return;
+ -- Optimize the case where we are using the default Global_Pool_Object,
+ -- and we don't need the heavy finalization machinery.
+
+ elsif Pool_Id = RTE (RE_Global_Pool_Object)
+ and then not Needs_Finalization (Desig_Typ)
+ then
+ return;
+
-- Do not replicate the machinery if the allocator / free has already
-- been expanded and has a custom Allocate / Deallocate.
diff --git a/gcc/ada/s-memory.adb b/gcc/ada/s-memory.adb
index b7d37d2..009efa2 100644
--- a/gcc/ada/s-memory.adb
+++ b/gcc/ada/s-memory.adb
@@ -6,7 +6,7 @@
-- --
-- B o d y --
-- --
--- Copyright (C) 2001-2013, Free Software Foundation, Inc. --
+-- Copyright (C) 2001-2016, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
@@ -43,14 +43,12 @@
pragma Compiler_Unit_Warning;
-with Ada.Exceptions;
-with System.Soft_Links;
-with System.Parameters;
with System.CRTL;
+with System.Parameters;
+with System.Soft_Links;
package body System.Memory is
- use Ada.Exceptions;
use System.Soft_Links;
function c_malloc (Size : System.CRTL.size_t) return System.Address
@@ -68,33 +66,41 @@ package body System.Memory is
-----------
function Alloc (Size : size_t) return System.Address is
- Result : System.Address;
- Actual_Size : size_t := Size;
-
+ Result : System.Address;
begin
- if Size = size_t'Last then
- Raise_Exception (Storage_Error'Identity, "object too large");
- end if;
-
- -- Change size from zero to non-zero. We still want a proper pointer
- -- for the zero case because pointers to zero length objects have to
- -- be distinct, but we can't just go ahead and allocate zero bytes,
- -- since some malloc's return zero for a zero argument.
-
- if Size = 0 then
- Actual_Size := 1;
- end if;
-
if Parameters.No_Abort then
- Result := c_malloc (System.CRTL.size_t (Actual_Size));
+ Result := c_malloc (System.CRTL.size_t (Size));
else
Abort_Defer.all;
- Result := c_malloc (System.CRTL.size_t (Actual_Size));
+ Result := c_malloc (System.CRTL.size_t (Size));
Abort_Undefer.all;
end if;
if Result = System.Null_Address then
- Raise_Exception (Storage_Error'Identity, "heap exhausted");
+ -- If Size = 0, we can't allocate 0 bytes, because then two different
+ -- allocators, one of which has Size = 0, could return pointers that
+ -- compare equal, which is wrong. (Nonnull pointers compare equal if
+ -- and only if they designate the same object, and two different
+ -- allocators allocate two different objects).
+
+ -- malloc(0) is defined to allocate a non-zero-sized object (in which
+ -- case we won't get here, and all is well) or NULL, in which case we
+ -- get here. We also get here in case of error. So check for the
+ -- zero-size case, and allocate 1 byte. Otherwise, raise
+ -- Storage_Error.
+
+ -- We check for zero size here, rather than at the start, for
+ -- efficiency.
+
+ if Size = 0 then
+ return Alloc (1);
+ end if;
+
+ if Size = size_t'Last then
+ raise Storage_Error with "object too large";
+ end if;
+
+ raise Storage_Error with "heap exhausted";
end if;
return Result;
@@ -125,23 +131,21 @@ package body System.Memory is
return System.Address
is
Result : System.Address;
- Actual_Size : constant size_t := Size;
-
begin
- if Size = size_t'Last then
- Raise_Exception (Storage_Error'Identity, "object too large");
- end if;
-
if Parameters.No_Abort then
- Result := c_realloc (Ptr, System.CRTL.size_t (Actual_Size));
+ Result := c_realloc (Ptr, System.CRTL.size_t (Size));
else
Abort_Defer.all;
- Result := c_realloc (Ptr, System.CRTL.size_t (Actual_Size));
+ Result := c_realloc (Ptr, System.CRTL.size_t (Size));
Abort_Undefer.all;
end if;
if Result = System.Null_Address then
- Raise_Exception (Storage_Error'Identity, "heap exhausted");
+ if Size = size_t'Last then
+ raise Storage_Error with "object too large";
+ end if;
+
+ raise Storage_Error with "heap exhausted";
end if;
return Result;