This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[Ada] Fix incorrect call to Pure function returning discriminated type
- From: Eric Botcazou <ebotcazou at adacore dot com>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 08 Apr 2015 11:08:22 +0200
- Subject: [Ada] Fix incorrect call to Pure function returning discriminated type
- Authentication-results: sourceware.org; auth=none
This disables incorrect optimization (mainly CSE) of calls to Pure functions
returning a discriminated record type. These functions allocate their return
value on the secondary stack and thus calls to them cannot be CSE'ed because
the stack can be reclaimed in between.
Tested on x86_64-suse-linux, applied on the mainline.
2015-04-08 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (gnat_to_gnu_entity) <E_Function>: Do not make
a function returning an unconstrained type 'const' for the middle-end.
2015-04-08 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/opt48.adb: New test.
* gnat.dg/opt48_pkg1.ad[sb]: New helper.
* gnat.dg/opt48_pkg2.ad[sb]: Likewise.
--
Eric Botcazou
Index: gcc-interface/decl.c
===================================================================
--- gcc-interface/decl.c (revision 221915)
+++ gcc-interface/decl.c (working copy)
@@ -4266,8 +4266,9 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
return_by_direct_ref_p = true;
}
- /* If we are supposed to return an unconstrained array type, make
- the actual return type the fat pointer type. */
+ /* If the return type is an unconstrained array type, the return
+ value will be allocated on the secondary stack so the actual
+ return type is the fat pointer type. */
else if (TREE_CODE (gnu_return_type) == UNCONSTRAINED_ARRAY_TYPE)
{
gnu_return_type = TREE_TYPE (gnu_return_type);
@@ -4275,8 +4276,8 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
}
/* Likewise, if the return type requires a transient scope, the
- return value will be allocated on the secondary stack so the
- actual return type is the pointer type. */
+ return value will also be allocated on the secondary stack so
+ the actual return type is the pointer type. */
else if (Requires_Transient_Scope (gnat_return_type))
{
gnu_return_type = build_pointer_type (gnu_return_type);
@@ -4591,11 +4592,14 @@ gnat_to_gnu_entity (Entity_Id gnat_entit
return_by_direct_ref_p,
return_by_invisi_ref_p);
- /* A subprogram (something that doesn't return anything) shouldn't
- be considered const since there would be no reason for such a
+ /* A procedure (something that doesn't return anything) shouldn't be
+ considered const since there would be no reason for calling such a
subprogram. Note that procedures with Out (or In Out) parameters
- have already been converted into a function with a return type. */
- if (TREE_CODE (gnu_return_type) == VOID_TYPE)
+ have already been converted into a function with a return type.
+ Similarly, if the function returns an unconstrained type, then the
+ function will allocate the return value on the secondary stack and
+ thus calls to it cannot be CSE'ed, lest the stack be reclaimed. */
+ if (TREE_CODE (gnu_return_type) == VOID_TYPE || return_unconstrained_p)
const_flag = false;
if (const_flag || volatile_flag)
-- { dg-do run }
-- { dg-options "-O" }
with Opt48_Pkg1; use Opt48_Pkg1;
with Opt48_Pkg2; use Opt48_Pkg2;
procedure Opt48 is
begin
if Get_Z /= (12, "Hello world!") then
raise Program_Error;
end if;
end;
package body Opt48_Pkg1 is
function G return Rec is
begin
return (32, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
end G;
X : Rec := F;
Y : Rec := G;
Z : Rec := F;
function Get_Z return Rec is
begin
return Z;
end;
end Opt48_Pkg1;
with Opt48_Pkg2; use Opt48_Pkg2;
package Opt48_Pkg1 is
function Get_Z return Rec;
end Opt48_Pkg1;
package body Opt48_Pkg2 is
function F return Rec is
begin
return (12, "Hello world!");
end F;
end Opt48_Pkg2;
package Opt48_Pkg2 is
pragma Pure;
type Rec (L : Natural) is record
S : String (1 .. L);
end record;
function F return Rec;
end Opt48_Pkg2;