Commit bdbebf66 by Eric Botcazou Committed by Eric Botcazou

utils2.c (build_allocator): Set TREE_THIS_NOTRAP on the dereference of the…

utils2.c (build_allocator): Set TREE_THIS_NOTRAP on the dereference of the pointer to the storage area.

	* gcc-interface/utils2.c (build_allocator): Set TREE_THIS_NOTRAP on the
	dereference of the pointer to the storage area.  Remove useless type
	conversions and factor out common code.

From-SVN: r179187
parent 1aa291f7
2011-09-26 Eric Botcazou <ebotcazou@adacore.com> 2011-09-26 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/utils2.c (build_allocator): Set TREE_THIS_NOTRAP on the
dereference of the pointer to the storage area. Remove useless type
conversions and factor out common code.
2011-09-26 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/utils.c (maybe_unconstrained_array): Declare TYPE local * gcc-interface/utils.c (maybe_unconstrained_array): Declare TYPE local
variable and use it throughout. variable and use it throughout.
<UNCONSTRAINED_ARRAY_TYPE>: Add 'break' at the end. <UNCONSTRAINED_ARRAY_TYPE>: Add 'break' at the end.
......
...@@ -2112,9 +2112,9 @@ build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, tree gnu_type, ...@@ -2112,9 +2112,9 @@ build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, tree gnu_type,
} }
} }
/* Build a GCC tree to correspond to allocating an object of TYPE whose /* Build a GCC tree that corresponds to allocating an object of TYPE whose
initial value is INIT, if INIT is nonzero. Convert the expression to initial value is INIT, if INIT is nonzero. Convert the expression to
RESULT_TYPE, which must be some type of pointer. Return the tree. RESULT_TYPE, which must be some pointer type, and return the result.
GNAT_PROC and GNAT_POOL optionally give the procedure to call and GNAT_PROC and GNAT_POOL optionally give the procedure to call and
the storage pool to use. GNAT_NODE is used to provide an error the storage pool to use. GNAT_NODE is used to provide an error
...@@ -2127,8 +2127,7 @@ tree ...@@ -2127,8 +2127,7 @@ tree
build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc, build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc,
Entity_Id gnat_pool, Node_Id gnat_node, bool ignore_init_type) Entity_Id gnat_pool, Node_Id gnat_node, bool ignore_init_type)
{ {
tree size = TYPE_SIZE_UNIT (type); tree size, storage, storage_deref, storage_init;
tree result;
/* If the initializer, if present, is a NULL_EXPR, just return a new one. */ /* If the initializer, if present, is a NULL_EXPR, just return a new one. */
if (init && TREE_CODE (init) == NULL_EXPR) if (init && TREE_CODE (init) == NULL_EXPR)
...@@ -2154,19 +2153,19 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc, ...@@ -2154,19 +2153,19 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc,
get_identifier ("ALLOC"), false); get_identifier ("ALLOC"), false);
tree template_type = TREE_TYPE (TYPE_FIELDS (storage_type)); tree template_type = TREE_TYPE (TYPE_FIELDS (storage_type));
tree storage_ptr_type = build_pointer_type (storage_type); tree storage_ptr_type = build_pointer_type (storage_type);
tree storage;
size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (storage_type), size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (storage_type),
init); init);
/* If the size overflows, pass -1 so the allocator will raise /* If the size overflows, pass -1 so Storage_Error will be raised. */
storage error. */
if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size)) if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size))
size = ssize_int (-1); size = ssize_int (-1);
storage = build_call_alloc_dealloc (NULL_TREE, size, storage_type, storage = build_call_alloc_dealloc (NULL_TREE, size, storage_type,
gnat_proc, gnat_pool, gnat_node); gnat_proc, gnat_pool, gnat_node);
storage = convert (storage_ptr_type, gnat_protect_expr (storage)); storage = convert (storage_ptr_type, gnat_protect_expr (storage));
storage_deref = build_unary_op (INDIRECT_REF, NULL_TREE, storage);
TREE_THIS_NOTRAP (storage_deref) = 1;
/* If there is an initializing expression, then make a constructor for /* If there is an initializing expression, then make a constructor for
the entire object including the bounds and copy it into the object. the entire object including the bounds and copy it into the object.
...@@ -2179,29 +2178,24 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc, ...@@ -2179,29 +2178,24 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc,
build_template (template_type, type, init)); build_template (template_type, type, init));
CONSTRUCTOR_APPEND_ELT (v, DECL_CHAIN (TYPE_FIELDS (storage_type)), CONSTRUCTOR_APPEND_ELT (v, DECL_CHAIN (TYPE_FIELDS (storage_type)),
init); init);
return convert storage_init
(result_type, = build_binary_op (MODIFY_EXPR, NULL_TREE, storage_deref,
build2 (COMPOUND_EXPR, storage_ptr_type, gnat_build_constructor (storage_type, v));
build_binary_op
(MODIFY_EXPR, NULL_TREE,
build_unary_op (INDIRECT_REF, NULL_TREE,
convert (storage_ptr_type, storage)),
gnat_build_constructor (storage_type, v)),
convert (storage_ptr_type, storage)));
} }
else else
return build2 storage_init
(COMPOUND_EXPR, result_type, = build_binary_op (MODIFY_EXPR, NULL_TREE,
build_binary_op build_component_ref (storage_deref, NULL_TREE,
(MODIFY_EXPR, NULL_TREE, TYPE_FIELDS (storage_type),
build_component_ref false),
(build_unary_op (INDIRECT_REF, NULL_TREE, build_template (template_type, type, NULL_TREE));
convert (storage_ptr_type, storage)),
NULL_TREE, TYPE_FIELDS (storage_type), false), return build2 (COMPOUND_EXPR, result_type,
build_template (template_type, type, NULL_TREE)), storage_init, convert (result_type, storage));
convert (result_type, convert (storage_ptr_type, storage)));
} }
size = TYPE_SIZE_UNIT (type);
/* If we have an initializing expression, see if its size is simpler /* If we have an initializing expression, see if its size is simpler
than the size from the type. */ than the size from the type. */
if (!ignore_init_type && init && TYPE_SIZE_UNIT (TREE_TYPE (init)) if (!ignore_init_type && init && TYPE_SIZE_UNIT (TREE_TYPE (init))
...@@ -2221,32 +2215,28 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc, ...@@ -2221,32 +2215,28 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc,
size = max_size (size, true); size = max_size (size, true);
} }
/* If the size overflows, pass -1 so the allocator will raise /* If the size overflows, pass -1 so Storage_Error will be raised. */
storage error. */
if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size)) if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size))
size = ssize_int (-1); size = ssize_int (-1);
result = convert (result_type, storage = convert (result_type,
build_call_alloc_dealloc (NULL_TREE, size, type, build_call_alloc_dealloc (NULL_TREE, size, type,
gnat_proc, gnat_pool, gnat_proc, gnat_pool,
gnat_node)); gnat_node));
/* If we have an initial value, protect the new address, assign the value /* If we have an initial value, protect the new address, assign the value
and return the address with a COMPOUND_EXPR. */ and return the address with a COMPOUND_EXPR. */
if (init) if (init)
{ {
result = gnat_protect_expr (result); storage = gnat_protect_expr (storage);
result storage_deref = build_unary_op (INDIRECT_REF, NULL_TREE, storage);
= build2 (COMPOUND_EXPR, TREE_TYPE (result), TREE_THIS_NOTRAP (storage_deref) = 1;
build_binary_op storage_init
(MODIFY_EXPR, NULL_TREE, = build_binary_op (MODIFY_EXPR, NULL_TREE, storage_deref, init);
build_unary_op (INDIRECT_REF, return build2 (COMPOUND_EXPR, result_type, storage_init, storage);
TREE_TYPE (TREE_TYPE (result)), result),
init),
result);
} }
return convert (result_type, result); return storage;
} }
/* Indicate that we need to take the address of T and that it therefore /* Indicate that we need to take the address of T and that it therefore
......
2011-09-26 Eric Botcazou <ebotcazou@adacore.com> 2011-09-26 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/opt20.ad[sb]: New test.
* gnat.dg/opt20_pkg.ads: New helper.
2011-09-26 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/array17.adb: New test. * gnat.dg/array17.adb: New test.
* gnat.dg/array17_pkg.ads: New helper. * gnat.dg/array17_pkg.ads: New helper.
......
with Ada.Characters.Handling; use Ada.Characters.Handling;
package body Opt20 is
type Build_Mode_State is (None, Static, Dynamic, Relocatable);
procedure Build_Library (For_Project : Integer) is
Project_Name : constant String := Get_Name_String (For_Project);
The_Build_Mode : Build_Mode_State := None;
begin
Fail (Project_Name);
Write_Str (To_Lower (Build_Mode_State'Image (The_Build_Mode)));
end;
end Opt20;
-- { dg-do compile }
-- { dg-options "-O2 -gnatpn" }
with Opt20_Pkg; use Opt20_Pkg;
package Opt20 is
procedure Build_Library (For_Project : Integer);
end Opt20;
package Opt20_Pkg is
procedure Write_Str (S : String);
type Fail_Proc is access procedure (S : String);
procedure My_Fail (S : String);
Fail : Fail_Proc := My_Fail'Access;
function Get_Name_String (Id : Integer) return String;
end Opt20_Pkg;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment