diff options
author | Eric Botcazou <ebotcazou@adacore.com> | 2011-09-26 09:21:01 +0000 |
---|---|---|
committer | Eric Botcazou <ebotcazou@gcc.gnu.org> | 2011-09-26 09:21:01 +0000 |
commit | bdbebf669ee8257685c2b6d1c501e899cd20bbea (patch) | |
tree | d5eeb530594acca7eb7796e2ee4c250e186964a1 | |
parent | 1aa291f7d1b8b9e89c4ad6be87e7553cb269c18f (diff) | |
download | gcc-bdbebf669ee8257685c2b6d1c501e899cd20bbea.zip gcc-bdbebf669ee8257685c2b6d1c501e899cd20bbea.tar.gz gcc-bdbebf669ee8257685c2b6d1c501e899cd20bbea.tar.bz2 |
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
-rw-r--r-- | gcc/ada/ChangeLog | 6 | ||||
-rw-r--r-- | gcc/ada/gcc-interface/utils2.c | 74 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/opt20.adb | 15 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/opt20.ads | 10 | ||||
-rw-r--r-- | gcc/testsuite/gnat.dg/opt20_pkg.ads | 13 |
6 files changed, 81 insertions, 42 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog index 4a4b64e..15ef0b5 100644 --- a/gcc/ada/ChangeLog +++ b/gcc/ada/ChangeLog @@ -1,5 +1,11 @@ 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 variable and use it throughout. <UNCONSTRAINED_ARRAY_TYPE>: Add 'break' at the end. diff --git a/gcc/ada/gcc-interface/utils2.c b/gcc/ada/gcc-interface/utils2.c index b9906b1..cf290a3 100644 --- a/gcc/ada/gcc-interface/utils2.c +++ b/gcc/ada/gcc-interface/utils2.c @@ -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 - 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 the storage pool to use. GNAT_NODE is used to provide an error @@ -2127,8 +2127,7 @@ tree 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) { - tree size = TYPE_SIZE_UNIT (type); - tree result; + tree size, storage, storage_deref, storage_init; /* If the initializer, if present, is a NULL_EXPR, just return a new one. */ if (init && TREE_CODE (init) == NULL_EXPR) @@ -2154,19 +2153,19 @@ build_allocator (tree type, tree init, tree result_type, Entity_Id gnat_proc, get_identifier ("ALLOC"), false); tree template_type = TREE_TYPE (TYPE_FIELDS (storage_type)); tree storage_ptr_type = build_pointer_type (storage_type); - tree storage; size = SUBSTITUTE_PLACEHOLDER_IN_EXPR (TYPE_SIZE_UNIT (storage_type), init); - /* If the size overflows, pass -1 so the allocator will raise - storage error. */ + /* If the size overflows, pass -1 so Storage_Error will be raised. */ if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size)) size = ssize_int (-1); storage = build_call_alloc_dealloc (NULL_TREE, size, storage_type, gnat_proc, gnat_pool, gnat_node); 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 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, build_template (template_type, type, init)); CONSTRUCTOR_APPEND_ELT (v, DECL_CHAIN (TYPE_FIELDS (storage_type)), init); - return convert - (result_type, - build2 (COMPOUND_EXPR, storage_ptr_type, - 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))); + storage_init + = build_binary_op (MODIFY_EXPR, NULL_TREE, storage_deref, + gnat_build_constructor (storage_type, v)); } else - return build2 - (COMPOUND_EXPR, result_type, - build_binary_op - (MODIFY_EXPR, NULL_TREE, - build_component_ref - (build_unary_op (INDIRECT_REF, NULL_TREE, - convert (storage_ptr_type, storage)), - NULL_TREE, TYPE_FIELDS (storage_type), false), - build_template (template_type, type, NULL_TREE)), - convert (result_type, convert (storage_ptr_type, storage))); + storage_init + = build_binary_op (MODIFY_EXPR, NULL_TREE, + build_component_ref (storage_deref, NULL_TREE, + TYPE_FIELDS (storage_type), + false), + build_template (template_type, type, NULL_TREE)); + + return build2 (COMPOUND_EXPR, result_type, + storage_init, convert (result_type, storage)); } + size = TYPE_SIZE_UNIT (type); + /* If we have an initializing expression, see if its size is simpler than the size from the type. */ 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, size = max_size (size, true); } - /* If the size overflows, pass -1 so the allocator will raise - storage error. */ + /* If the size overflows, pass -1 so Storage_Error will be raised. */ if (TREE_CODE (size) == INTEGER_CST && TREE_OVERFLOW (size)) size = ssize_int (-1); - result = convert (result_type, - build_call_alloc_dealloc (NULL_TREE, size, type, - gnat_proc, gnat_pool, - gnat_node)); + storage = convert (result_type, + build_call_alloc_dealloc (NULL_TREE, size, type, + gnat_proc, gnat_pool, + gnat_node)); /* If we have an initial value, protect the new address, assign the value and return the address with a COMPOUND_EXPR. */ if (init) { - result = gnat_protect_expr (result); - result - = build2 (COMPOUND_EXPR, TREE_TYPE (result), - build_binary_op - (MODIFY_EXPR, NULL_TREE, - build_unary_op (INDIRECT_REF, - TREE_TYPE (TREE_TYPE (result)), result), - init), - result); + storage = gnat_protect_expr (storage); + storage_deref = build_unary_op (INDIRECT_REF, NULL_TREE, storage); + TREE_THIS_NOTRAP (storage_deref) = 1; + storage_init + = build_binary_op (MODIFY_EXPR, NULL_TREE, storage_deref, init); + return build2 (COMPOUND_EXPR, result_type, storage_init, storage); } - return convert (result_type, result); + return storage; } /* Indicate that we need to take the address of T and that it therefore diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 8f11de1..e7e2594 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,5 +1,10 @@ 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_pkg.ads: New helper. diff --git a/gcc/testsuite/gnat.dg/opt20.adb b/gcc/testsuite/gnat.dg/opt20.adb new file mode 100644 index 0000000..6d3e240 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt20.adb @@ -0,0 +1,15 @@ +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; diff --git a/gcc/testsuite/gnat.dg/opt20.ads b/gcc/testsuite/gnat.dg/opt20.ads new file mode 100644 index 0000000..58833bf --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt20.ads @@ -0,0 +1,10 @@ +-- { dg-do compile } +-- { dg-options "-O2 -gnatpn" } + +with Opt20_Pkg; use Opt20_Pkg; + +package Opt20 is + + procedure Build_Library (For_Project : Integer); + +end Opt20; diff --git a/gcc/testsuite/gnat.dg/opt20_pkg.ads b/gcc/testsuite/gnat.dg/opt20_pkg.ads new file mode 100644 index 0000000..2b9b3e8 --- /dev/null +++ b/gcc/testsuite/gnat.dg/opt20_pkg.ads @@ -0,0 +1,13 @@ +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; |