aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/gcc-interface/decl.c
diff options
context:
space:
mode:
authorEric Botcazou <ebotcazou@adacore.com>2018-07-07 10:06:08 +0000
committerEric Botcazou <ebotcazou@gcc.gnu.org>2018-07-07 10:06:08 +0000
commit718364340fa052641189523e41a5006ba6c9966d (patch)
tree570d31e7786608bb116879802c177ebeb03e7bd4 /gcc/ada/gcc-interface/decl.c
parent4a669ac35988fa6de5931455fb59c713563bc58b (diff)
downloadgcc-718364340fa052641189523e41a5006ba6c9966d.zip
gcc-718364340fa052641189523e41a5006ba6c9966d.tar.gz
gcc-718364340fa052641189523e41a5006ba6c9966d.tar.bz2
decl.c (gnat_to_gnu_param): Minor tweak.
* gcc-interface/decl.c (gnat_to_gnu_param): Minor tweak. (gnat_to_gnu_subprog_type): New pure_flag local variable. Set it for a pure Ada function with a by-ref In parameter. Propagate it onto the function type by means of the TYPE_QUAL_RESTRICT flag. * gcc-interface/utils.c (finish_subprog_decl): Set DECL_PURE_P if the function type has the TYPE_QUAL_RESTRICT flag set. From-SVN: r262495
Diffstat (limited to 'gcc/ada/gcc-interface/decl.c')
-rw-r--r--gcc/ada/gcc-interface/decl.c36
1 files changed, 23 insertions, 13 deletions
diff --git a/gcc/ada/gcc-interface/decl.c b/gcc/ada/gcc-interface/decl.c
index 82a4492..def48f1 100644
--- a/gcc/ada/gcc-interface/decl.c
+++ b/gcc/ada/gcc-interface/decl.c
@@ -5228,7 +5228,6 @@ gnat_to_gnu_param (Entity_Id gnat_param, tree gnu_param_type, bool first,
&& TYPE_MULTI_ARRAY_P (TREE_TYPE (gnu_param_type)))
gnu_param_type = TREE_TYPE (gnu_param_type);
- by_component_ptr = true;
gnu_param_type = TREE_TYPE (gnu_param_type);
if (ro_param)
@@ -5236,6 +5235,7 @@ gnat_to_gnu_param (Entity_Id gnat_param, tree gnu_param_type, bool first,
= change_qualified_type (gnu_param_type, TYPE_QUAL_CONST);
gnu_param_type = build_pointer_type (gnu_param_type);
+ by_component_ptr = true;
}
/* Fat pointers are passed as thin pointers for foreign conventions. */
@@ -5561,14 +5561,15 @@ gnat_to_gnu_subprog_type (Entity_Id gnat_subprog, bool definition,
/* Fields in return type of procedure with copy-in copy-out parameters. */
tree gnu_field_list = NULL_TREE;
/* The semantics of "pure" in Ada essentially matches that of "const"
- in the back-end. In particular, both properties are orthogonal to
- the "nothrow" property if the EH circuitry is explicit in the
- internal representation of the back-end. If we are to completely
+ or "pure" in GCC. In particular, both properties are orthogonal
+ to the "nothrow" property if the EH circuitry is explicit in the
+ internal representation of the middle-end. If we are to completely
hide the EH circuitry from it, we need to declare that calls to pure
Ada subprograms that can throw have side effects since they can
- trigger an "abnormal" transfer of control flow; thus they can be
- neither "const" nor "pure" in the back-end sense. */
+ trigger an "abnormal" transfer of control flow; therefore, they can
+ be neither "const" nor "pure" in the GCC sense. */
bool const_flag = (Back_End_Exceptions () && Is_Pure (gnat_subprog));
+ bool pure_flag = false;
bool return_by_direct_ref_p = false;
bool return_by_invisi_ref_p = false;
bool return_unconstrained_p = false;
@@ -5849,13 +5850,19 @@ gnat_to_gnu_subprog_type (Entity_Id gnat_subprog, bool definition,
gnu_param_list = chainon (gnu_param, gnu_param_list);
save_gnu_tree (gnat_param, gnu_param, false);
- /* If a parameter is a pointer, a function may modify memory through
- it and thus shouldn't be considered a const function. Also, the
- memory may be modified between two calls, so they can't be CSE'ed.
- The latter case also handles by-ref parameters. */
- if (POINTER_TYPE_P (gnu_param_type)
- || TYPE_IS_FAT_POINTER_P (gnu_param_type))
- const_flag = false;
+ /* A pure function in the Ada sense which takes an access parameter
+ may modify memory through it and thus need be considered neither
+ const nor pure in the GCC sense. Likewise it if takes a by-ref
+ In Out or Out parameter. But if it takes a by-ref In parameter,
+ then it may only read memory through it and can be considered
+ pure in the GCC sense. */
+ if ((const_flag || pure_flag)
+ && (POINTER_TYPE_P (gnu_param_type)
+ || TYPE_IS_FAT_POINTER_P (gnu_param_type)))
+ {
+ const_flag = false;
+ pure_flag = DECL_POINTS_TO_READONLY_P (gnu_param);
+ }
}
/* If the parameter uses the copy-in copy-out mechanism, allocate a field
@@ -6007,6 +6014,9 @@ gnat_to_gnu_subprog_type (Entity_Id gnat_subprog, bool definition,
if (const_flag)
gnu_type = change_qualified_type (gnu_type, TYPE_QUAL_CONST);
+ if (pure_flag)
+ gnu_type = change_qualified_type (gnu_type, TYPE_QUAL_RESTRICT);
+
if (No_Return (gnat_subprog))
gnu_type = change_qualified_type (gnu_type, TYPE_QUAL_VOLATILE);