[Ada] Extend No_Dependence restriction to code generation
This reports violations for 4 units from gigi. gcc/ada/ * gcc-interface/trans.cc (gigi): Report a violation of No_Dependence on System.Stack_Checking if Stack_Check_Probes_On_Target is not set and -fstack-check is specified. (build_binary_op_trapv): Report violatiosn of No_Dependence on both System.Arith_64 and System.Arith_128. (add_decl_expr): If an initialized variable, report a violation of No_Dependence on System.Memory_Copy for large aggregate types. (gnat_to_gnu) <N_Op_Eq>: Report a violation of No_Dependence on System.Memory_Compare for large aggregate types. <N_Assignment_Statement>! Report a violation of No_Dependence on System.Memory_Set, System.Memory_Move or else System.Memory_Copy for large aggregate types. * gcc-interface/utils2.cc (maybe_wrap_malloc): Report a violation of No_Dependence on System.Memory. (maybe_wrap_free): Add GNAT_NODE parameter and report a violation of No_Dependence on System.Memory. (build_call_alloc_dealloc): Adjust call to maybe_wrap_free.
This commit is contained in:
parent
351659f8dc
commit
1f3f64b9e7
2 changed files with 64 additions and 21 deletions
|
@ -364,7 +364,12 @@ gigi (Node_Id gnat_root,
|
|||
|
||||
/* Enable GNAT stack checking method if needed */
|
||||
if (!Stack_Check_Probes_On_Target)
|
||||
set_stack_check_libfunc ("__gnat_stack_check");
|
||||
{
|
||||
set_stack_check_libfunc ("__gnat_stack_check");
|
||||
if (flag_stack_check != NO_STACK_CHECK)
|
||||
Check_Restriction_No_Dependence_On_System (Name_Stack_Checking,
|
||||
gnat_root);
|
||||
}
|
||||
|
||||
/* Retrieve alignment settings. */
|
||||
double_float_alignment = get_target_double_float_alignment ();
|
||||
|
@ -6933,9 +6938,18 @@ gnat_to_gnu (Node_Id gnat_node)
|
|||
= convert (TREE_TYPE (gnu_rhs), TYPE_SIZE (gnu_type));
|
||||
}
|
||||
|
||||
/* If this is a comparison between (potentially) large aggregates, then
|
||||
declare the dependence on the memcmp routine. */
|
||||
else if ((kind == N_Op_Eq || kind == N_Op_Ne)
|
||||
&& AGGREGATE_TYPE_P (TREE_TYPE (gnu_lhs))
|
||||
&& (!TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_lhs)))
|
||||
|| compare_tree_int (TYPE_SIZE (TREE_TYPE (gnu_lhs)),
|
||||
2 * BITS_PER_WORD) > 0))
|
||||
Check_Restriction_No_Dependence_On_System (Name_Memory_Compare,
|
||||
gnat_node);
|
||||
|
||||
/* Pending generic support for efficient vector logical operations in
|
||||
GCC, convert vectors to their representative array type view and
|
||||
fallthrough. */
|
||||
GCC, convert vectors to their representative array type view. */
|
||||
gnu_lhs = maybe_vector_array (gnu_lhs);
|
||||
gnu_rhs = maybe_vector_array (gnu_rhs);
|
||||
|
||||
|
@ -7254,6 +7268,8 @@ gnat_to_gnu (Node_Id gnat_node)
|
|||
value = int_const_binop (BIT_AND_EXPR, value, mask);
|
||||
}
|
||||
gnu_result = build_call_expr (t, 3, dest, value, size);
|
||||
Check_Restriction_No_Dependence_On_System (Name_Memory_Set,
|
||||
gnat_node);
|
||||
}
|
||||
|
||||
/* Otherwise build a regular assignment. */
|
||||
|
@ -7278,7 +7294,18 @@ gnat_to_gnu (Node_Id gnat_node)
|
|||
tree from_ptr = build_fold_addr_expr (from);
|
||||
tree t = builtin_decl_explicit (BUILT_IN_MEMMOVE);
|
||||
gnu_result = build_call_expr (t, 3, to_ptr, from_ptr, size);
|
||||
Check_Restriction_No_Dependence_On_System (Name_Memory_Move,
|
||||
gnat_node);
|
||||
}
|
||||
|
||||
/* If this is an assignment between (potentially) large aggregates,
|
||||
then declare the dependence on the memcpy routine. */
|
||||
else if (AGGREGATE_TYPE_P (TREE_TYPE (gnu_lhs))
|
||||
&& (!TREE_CONSTANT (TYPE_SIZE (TREE_TYPE (gnu_lhs)))
|
||||
|| compare_tree_int (TYPE_SIZE (TREE_TYPE (gnu_lhs)),
|
||||
2 * BITS_PER_WORD) > 0))
|
||||
Check_Restriction_No_Dependence_On_System (Name_Memory_Copy,
|
||||
gnat_node);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -8437,27 +8464,37 @@ add_decl_expr (tree gnu_decl, Node_Id gnat_node)
|
|||
&& !TYPE_FAT_POINTER_P (type))
|
||||
MARK_VISITED (TYPE_ADA_SIZE (type));
|
||||
|
||||
/* If this is a variable and an initializer is attached to it, it must be
|
||||
valid for the context. Similar to init_const in create_var_decl. */
|
||||
if (TREE_CODE (gnu_decl) == VAR_DECL
|
||||
&& (gnu_init = DECL_INITIAL (gnu_decl))
|
||||
&& (!gnat_types_compatible_p (type, TREE_TYPE (gnu_init))
|
||||
if (TREE_CODE (gnu_decl) == VAR_DECL && (gnu_init = DECL_INITIAL (gnu_decl)))
|
||||
{
|
||||
/* If this is a variable and an initializer is attached to it, it must be
|
||||
valid for the context. Similar to init_const in create_var_decl. */
|
||||
if (!gnat_types_compatible_p (type, TREE_TYPE (gnu_init))
|
||||
|| (TREE_STATIC (gnu_decl)
|
||||
&& !initializer_constant_valid_p (gnu_init,
|
||||
TREE_TYPE (gnu_init)))))
|
||||
{
|
||||
DECL_INITIAL (gnu_decl) = NULL_TREE;
|
||||
if (TREE_READONLY (gnu_decl))
|
||||
TREE_TYPE (gnu_init))))
|
||||
{
|
||||
TREE_READONLY (gnu_decl) = 0;
|
||||
DECL_READONLY_ONCE_ELAB (gnu_decl) = 1;
|
||||
DECL_INITIAL (gnu_decl) = NULL_TREE;
|
||||
if (TREE_READONLY (gnu_decl))
|
||||
{
|
||||
TREE_READONLY (gnu_decl) = 0;
|
||||
DECL_READONLY_ONCE_ELAB (gnu_decl) = 1;
|
||||
}
|
||||
|
||||
/* Remove any padding so the assignment is done properly. */
|
||||
gnu_decl = maybe_padded_object (gnu_decl);
|
||||
|
||||
gnu_stmt
|
||||
= build_binary_op (INIT_EXPR, NULL_TREE, gnu_decl, gnu_init);
|
||||
add_stmt_with_node (gnu_stmt, gnat_node);
|
||||
}
|
||||
|
||||
/* Remove any padding so the assignment is done properly. */
|
||||
gnu_decl = maybe_padded_object (gnu_decl);
|
||||
|
||||
gnu_stmt = build_binary_op (INIT_EXPR, NULL_TREE, gnu_decl, gnu_init);
|
||||
add_stmt_with_node (gnu_stmt, gnat_node);
|
||||
/* If this is the initialization of a (potentially) large aggregate, then
|
||||
declare the dependence on the memcpy routine. */
|
||||
if (AGGREGATE_TYPE_P (type)
|
||||
&& (!TREE_CONSTANT (TYPE_SIZE (type))
|
||||
|| compare_tree_int (TYPE_SIZE (type), 2 * BITS_PER_WORD) > 0))
|
||||
Check_Restriction_No_Dependence_On_System (Name_Memory_Copy,
|
||||
gnat_node);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -9359,6 +9396,7 @@ build_binary_op_trapv (enum tree_code code, tree gnu_type, tree left,
|
|||
if (code == MULT_EXPR && precision == 64 && BITS_PER_WORD < 64)
|
||||
{
|
||||
tree int64 = gnat_type_for_size (64, 0);
|
||||
Check_Restriction_No_Dependence_On_System (Name_Arith_64, gnat_node);
|
||||
return convert (gnu_type, build_call_n_expr (mulv64_decl, 2,
|
||||
convert (int64, lhs),
|
||||
convert (int64, rhs)));
|
||||
|
@ -9368,6 +9406,7 @@ build_binary_op_trapv (enum tree_code code, tree gnu_type, tree left,
|
|||
else if (code == MULT_EXPR && precision == 128 && BITS_PER_WORD < 128)
|
||||
{
|
||||
tree int128 = gnat_type_for_size (128, 0);
|
||||
Check_Restriction_No_Dependence_On_System (Name_Arith_128, gnat_node);
|
||||
return convert (gnu_type, build_call_n_expr (mulv128_decl, 2,
|
||||
convert (int128, lhs),
|
||||
convert (int128, rhs)));
|
||||
|
|
|
@ -2259,6 +2259,8 @@ maybe_wrap_malloc (tree data_size, tree data_type, Node_Id gnat_node)
|
|||
|
||||
tree malloc_ptr = build_call_n_expr (malloc_decl, 1, size_to_malloc);
|
||||
|
||||
Check_Restriction_No_Dependence_On_System (Name_Memory, gnat_node);
|
||||
|
||||
if (aligning_type)
|
||||
{
|
||||
/* Latch malloc's return value and get a pointer to the aligning field
|
||||
|
@ -2305,7 +2307,7 @@ maybe_wrap_malloc (tree data_size, tree data_type, Node_Id gnat_node)
|
|||
designated by DATA_PTR using the __gnat_free entry point. */
|
||||
|
||||
static inline tree
|
||||
maybe_wrap_free (tree data_ptr, tree data_type)
|
||||
maybe_wrap_free (tree data_ptr, tree data_type, Node_Id gnat_node)
|
||||
{
|
||||
/* In the regular alignment case, we pass the data pointer straight to free.
|
||||
In the superaligned case, we need to retrieve the initial allocator
|
||||
|
@ -2317,6 +2319,8 @@ maybe_wrap_free (tree data_ptr, tree data_type)
|
|||
|
||||
tree free_ptr;
|
||||
|
||||
Check_Restriction_No_Dependence_On_System (Name_Memory, gnat_node);
|
||||
|
||||
if (data_align > system_allocator_alignment)
|
||||
{
|
||||
/* DATA_FRONT_PTR (void *)
|
||||
|
@ -2363,7 +2367,7 @@ build_call_alloc_dealloc (tree gnu_obj, tree gnu_size, tree gnu_type,
|
|||
/* Otherwise, object to "free" or "malloc" with possible special processing
|
||||
for alignments stricter than what the default allocator honors. */
|
||||
else if (gnu_obj)
|
||||
return maybe_wrap_free (gnu_obj, gnu_type);
|
||||
return maybe_wrap_free (gnu_obj, gnu_type, gnat_node);
|
||||
else
|
||||
{
|
||||
/* Assert that we no longer can be called with this special pool. */
|
||||
|
|
Loading…
Add table
Reference in a new issue