Commit 0274dd3f by Eric Botcazou Committed by Eric Botcazou

fe.h (Suppress_Checks): Declare.

	* fe.h (Suppress_Checks): Declare.
	* gcc-interface/misc.c (gnat_init_gcc_eh): Set -fnon-call-exceptions
	only if checks are not suppressed and -faggressive-loop-optimizations
	only if they are.
	* gcc-interface/trans.c (struct loop_info_d): Remove has_checks and
	warned_aggressive_loop_optimizations fields.
	(gigi): Do not clear warn_aggressive_loop_optimizations here.
	(Raise_Error_to_gnu): Do not set has_checks.
	(gnat_to_gnu) <N_Indexed_Component>: Remove support for aggressive
	loop optimizations.

From-SVN: r265921
parent 4174a33a
2018-11-08 Eric Botcazou <ebotcazou@adacore.com> 2018-11-08 Eric Botcazou <ebotcazou@adacore.com>
* fe.h (Suppress_Checks): Declare.
* gcc-interface/misc.c (gnat_init_gcc_eh): Set -fnon-call-exceptions
only if checks are not suppressed and -faggressive-loop-optimizations
only if they are.
* gcc-interface/trans.c (struct loop_info_d): Remove has_checks and
warned_aggressive_loop_optimizations fields.
(gigi): Do not clear warn_aggressive_loop_optimizations here.
(Raise_Error_to_gnu): Do not set has_checks.
(gnat_to_gnu) <N_Indexed_Component>: Remove support for aggressive
loop optimizations.
2018-11-08 Eric Botcazou <ebotcazou@adacore.com>
* gcc-interface/decl.c (components_to_record): Remove obsolete kludge. * gcc-interface/decl.c (components_to_record): Remove obsolete kludge.
* gcc-interface/utils.c (make_packable_type): Set TYPE_PACKED on the * gcc-interface/utils.c (make_packable_type): Set TYPE_PACKED on the
new type but do not take into account the setting on the old type for new type but do not take into account the setting on the old type for
......
...@@ -193,6 +193,7 @@ extern Boolean In_Same_Source_Unit (Node_Id, Node_Id); ...@@ -193,6 +193,7 @@ extern Boolean In_Same_Source_Unit (Node_Id, Node_Id);
#define GNAT_Mode opt__gnat_mode #define GNAT_Mode opt__gnat_mode
#define List_Representation_Info opt__list_representation_info #define List_Representation_Info opt__list_representation_info
#define No_Strict_Aliasing_CP opt__no_strict_aliasing #define No_Strict_Aliasing_CP opt__no_strict_aliasing
#define Suppress_Checks opt__suppress_checks
typedef enum { typedef enum {
Front_End_SJLJ, Back_End_ZCX, Back_End_SJLJ Front_End_SJLJ, Back_End_ZCX, Back_End_SJLJ
...@@ -207,6 +208,7 @@ extern Boolean Generate_SCO_Instance_Table; ...@@ -207,6 +208,7 @@ extern Boolean Generate_SCO_Instance_Table;
extern Boolean GNAT_Mode; extern Boolean GNAT_Mode;
extern Int List_Representation_Info; extern Int List_Representation_Info;
extern Boolean No_Strict_Aliasing_CP; extern Boolean No_Strict_Aliasing_CP;
extern Boolean Suppress_Checks;
#define ZCX_Exceptions opt__zcx_exceptions #define ZCX_Exceptions opt__zcx_exceptions
#define SJLJ_Exceptions opt__sjlj_exceptions #define SJLJ_Exceptions opt__sjlj_exceptions
......
...@@ -392,7 +392,7 @@ gnat_init_gcc_eh (void) ...@@ -392,7 +392,7 @@ gnat_init_gcc_eh (void)
using_eh_for_cleanups (); using_eh_for_cleanups ();
/* Turn on -fexceptions, -fnon-call-exceptions and -fdelete-dead-exceptions. /* Turn on -fexceptions, -fnon-call-exceptions and -fdelete-dead-exceptions.
The first one triggers the generation of the necessary exception tables. The first one activates the support for exceptions in the compiler.
The second one is useful for two reasons: 1/ we map some asynchronous The second one is useful for two reasons: 1/ we map some asynchronous
signals like SEGV to exceptions, so we need to ensure that the insns signals like SEGV to exceptions, so we need to ensure that the insns
which can lead to such signals are correctly attached to the exception which can lead to such signals are correctly attached to the exception
...@@ -402,10 +402,18 @@ gnat_init_gcc_eh (void) ...@@ -402,10 +402,18 @@ gnat_init_gcc_eh (void)
for such calls to actually raise in Ada. for such calls to actually raise in Ada.
The third one is an optimization that makes it possible to delete dead The third one is an optimization that makes it possible to delete dead
instructions that may throw exceptions, most notably loads and stores, instructions that may throw exceptions, most notably loads and stores,
as permitted in Ada. */ as permitted in Ada.
Turn off -faggressive-loop-optimizations because it may optimize away
out-of-bound array accesses that we want to be able to catch.
If checks are disabled, we use the same settings as the C++ compiler. */
flag_exceptions = 1; flag_exceptions = 1;
flag_non_call_exceptions = 1;
flag_delete_dead_exceptions = 1; flag_delete_dead_exceptions = 1;
if (!Suppress_Checks)
{
flag_non_call_exceptions = 1;
flag_aggressive_loop_optimizations = 0;
warn_aggressive_loop_optimizations = 0;
}
init_eh (); init_eh ();
} }
......
...@@ -198,8 +198,6 @@ struct GTY(()) loop_info_d { ...@@ -198,8 +198,6 @@ struct GTY(()) loop_info_d {
tree high_bound; tree high_bound;
vec<range_check_info, va_gc> *checks; vec<range_check_info, va_gc> *checks;
bool artificial; bool artificial;
bool has_checks;
bool warned_aggressive_loop_optimizations;
}; };
typedef struct loop_info_d *loop_info; typedef struct loop_info_d *loop_info;
...@@ -679,10 +677,6 @@ gigi (Node_Id gnat_root, ...@@ -679,10 +677,6 @@ gigi (Node_Id gnat_root,
/* Now translate the compilation unit proper. */ /* Now translate the compilation unit proper. */
Compilation_Unit_to_gnu (gnat_root); Compilation_Unit_to_gnu (gnat_root);
/* Disable -Waggressive-loop-optimizations since we implement our own
version of the warning. */
warn_aggressive_loop_optimizations = 0;
/* Then process the N_Validate_Unchecked_Conversion nodes. We do this at /* Then process the N_Validate_Unchecked_Conversion nodes. We do this at
the very end to avoid having to second-guess the front-end when we run the very end to avoid having to second-guess the front-end when we run
into dummy nodes during the regular processing. */ into dummy nodes during the regular processing. */
...@@ -5720,7 +5714,6 @@ Raise_Error_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p) ...@@ -5720,7 +5714,6 @@ Raise_Error_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p)
rci->inserted_cond rci->inserted_cond
= build1 (SAVE_EXPR, boolean_type_node, boolean_true_node); = build1 (SAVE_EXPR, boolean_type_node, boolean_true_node);
vec_safe_push (loop->checks, rci); vec_safe_push (loop->checks, rci);
loop->has_checks = true;
gnu_cond = build_noreturn_cond (gnat_to_gnu (gnat_cond)); gnu_cond = build_noreturn_cond (gnat_to_gnu (gnat_cond));
if (flag_unswitch_loops) if (flag_unswitch_loops)
gnu_cond = build_binary_op (TRUTH_ANDIF_EXPR, gnu_cond = build_binary_op (TRUTH_ANDIF_EXPR,
...@@ -5733,14 +5726,6 @@ Raise_Error_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p) ...@@ -5733,14 +5726,6 @@ Raise_Error_to_gnu (Node_Id gnat_node, tree *gnu_result_type_p)
gnu_cond, gnu_cond,
rci->inserted_cond); rci->inserted_cond);
} }
/* Or else, if aggressive loop optimizations are enabled, we just
record that there are checks applied to iteration variables. */
else if (optimize
&& flag_aggressive_loop_optimizations
&& inside_loop_p ()
&& (loop = find_loop_for (gnu_index)))
loop->has_checks = true;
} }
break; break;
...@@ -6359,45 +6344,9 @@ gnat_to_gnu (Node_Id gnat_node) ...@@ -6359,45 +6344,9 @@ gnat_to_gnu (Node_Id gnat_node)
gcc_assert (TREE_CODE (gnu_type) == ARRAY_TYPE); gcc_assert (TREE_CODE (gnu_type) == ARRAY_TYPE);
gnat_temp = gnat_expr_array[i]; gnat_temp = gnat_expr_array[i];
gnu_expr = maybe_character_value (gnat_to_gnu (gnat_temp)); gnu_expr = maybe_character_value (gnat_to_gnu (gnat_temp));
struct loop_info_d *loop;
gnu_result gnu_result
= build_binary_op (ARRAY_REF, NULL_TREE, gnu_result, gnu_expr); = build_binary_op (ARRAY_REF, NULL_TREE, gnu_result, gnu_expr);
/* Array accesses are bound-checked so they cannot trap, but this
is valid only if they are not hoisted ahead of the check. We
need to mark them as no-trap to get decent loop optimizations
in the presence of -fnon-call-exceptions, so we do it when we
know that the original expression had no side-effects. */
if (TREE_CODE (gnu_result) == ARRAY_REF
&& !(Nkind (gnat_temp) == N_Identifier
&& Ekind (Entity (gnat_temp)) == E_Constant))
TREE_THIS_NOTRAP (gnu_result) = 1;
/* If aggressive loop optimizations are enabled, we warn for loops
overrunning a simple array of size 1 not at the end of a record.
This is aimed to catch misuses of the trailing array idiom. */
if (optimize
&& flag_aggressive_loop_optimizations
&& inside_loop_p ()
&& TREE_CODE (TREE_TYPE (gnu_type)) != ARRAY_TYPE
&& TREE_CODE (gnu_array_object) != ARRAY_REF
&& tree_int_cst_equal (TYPE_MIN_VALUE (TYPE_DOMAIN (gnu_type)),
TYPE_MAX_VALUE (TYPE_DOMAIN (gnu_type)))
&& !array_at_struct_end_p (gnu_result)
&& (loop = find_loop_for (gnu_expr))
&& !loop->artificial
&& !loop->has_checks
&& tree_int_cst_equal (TYPE_MIN_VALUE (TYPE_DOMAIN (gnu_type)),
loop->low_bound)
&& can_be_lower_p (loop->low_bound, loop->high_bound)
&& !loop->warned_aggressive_loop_optimizations
&& warning (OPT_Waggressive_loop_optimizations,
"out-of-bounds access may be optimized away"))
{
inform (EXPR_LOCATION (loop->stmt), "containing loop");
loop->warned_aggressive_loop_optimizations = true;
}
} }
gnu_result_type = get_unpadded_type (Etype (gnat_node)); gnu_result_type = get_unpadded_type (Etype (gnat_node));
......
2018-11-08 Eric Botcazou <ebotcazou@adacore.com>
* gnat.dg/null_pointer_deref1.adb: Remove -gnatp and add pragma.
* gnat.dg/null_pointer_deref2.adb: Likewise.
* gnat.dg/null_pointer_deref3.adb: Likewise.
* gnat.dg/opt74.adb: New test.
* gnat.dg/opt74_pkg.ad[sb]: New helper.
* gnat.dg/warn12.adb: Delete.
* gnat.dg/warn12_pkg.ads: Likewise.
2018-11-08 David Malcolm <dmalcolm@redhat.com> 2018-11-08 David Malcolm <dmalcolm@redhat.com>
PR ipa/86395 PR ipa/86395
......
-- { dg-do run } -- { dg-do run }
-- { dg-options "-gnatp" }
-- This test requires architecture- and OS-specific support code for unwinding -- This test requires architecture- and OS-specific support code for unwinding
-- through signal frames (typically located in *-unwind.h) to pass. Feel free -- through signal frames (typically located in *-unwind.h) to pass. Feel free
-- to disable it if this code hasn't been implemented yet. -- to disable it if this code hasn't been implemented yet.
procedure Null_Pointer_Deref1 is procedure Null_Pointer_Deref1 is
pragma Suppress (All_Checks);
type Int_Ptr is access all Integer; type Int_Ptr is access all Integer;
function Ident return Int_Ptr is function Ident return Int_Ptr is
......
-- { dg-do run } -- { dg-do run }
-- { dg-options "-gnatp" }
-- This test requires architecture- and OS-specific support code for unwinding -- This test requires architecture- and OS-specific support code for unwinding
-- through signal frames (typically located in *-unwind.h) to pass. Feel free -- through signal frames (typically located in *-unwind.h) to pass. Feel free
...@@ -7,6 +6,8 @@ ...@@ -7,6 +6,8 @@
procedure Null_Pointer_Deref2 is procedure Null_Pointer_Deref2 is
pragma Suppress (All_Checks);
task T; task T;
task body T is task body T is
......
-- { dg-do run } -- { dg-do run }
-- { dg-options "-O -gnatp" }
-- This test requires architecture- and OS-specific support code for unwinding -- This test requires architecture- and OS-specific support code for unwinding
-- through signal frames (typically located in *-unwind.h) to pass. Feel free -- through signal frames (typically located in *-unwind.h) to pass. Feel free
...@@ -7,6 +6,8 @@ ...@@ -7,6 +6,8 @@
procedure Null_Pointer_Deref3 is procedure Null_Pointer_Deref3 is
pragma Suppress (All_Checks);
procedure Leaf is procedure Leaf is
type Int_Ptr is access all Integer; type Int_Ptr is access all Integer;
function n return Int_Ptr is function n return Int_Ptr is
......
-- { dg-do run }
-- { dg-options "-O2" }
with Opt74_Pkg; use Opt74_Pkg;
procedure Opt74 is
Index, Found : Integer;
begin
Proc (Found, Index);
if Found = 1 then
raise Program_Error;
end if;
end;
package body Opt74_Pkg is
procedure Proc (Found : out Integer; Index : out Integer) is
begin
Index := 1;
Found := 0;
while (Index <= A'Last) and (Found = 0) loop
if A (Index) = 2 then
Found := 1;
else
Index := Index + 1;
end if;
end loop;
end;
end Opt74_Pkg;
package Opt74_Pkg is
A : array (1 .. 10) of Integer := (others => 0);
procedure Proc (Found : out Integer; Index : out Integer);
end Opt74_Pkg;
-- { dg-do compile }
-- { dg-options "-O2" }
with Text_IO; use Text_IO;
with System.Storage_Elements; use System.Storage_Elements;
with Warn12_Pkg; use Warn12_Pkg;
procedure Warn12 (N : Natural) is
Buffer_Size : constant Storage_Offset
:= Token_Groups'Size/System.Storage_Unit + 4096;
Buffer : Storage_Array (1 .. Buffer_Size);
for Buffer'Alignment use 8;
Tg1 : Token_Groups;
for Tg1'Address use Buffer'Address;
Tg2 : Token_Groups;
pragma Warnings (Off, Tg2);
sid : Sid_And_Attributes;
pragma Suppress (Index_Check, Sid_And_Attributes_Array);
begin
for I in 0 .. 7 loop
sid := Tg1.Groups(I); -- { dg-bogus "out-of-bounds access" }
Put_Line("Iteration");
end loop;
for I in 0 .. N loop
sid := Tg1.Groups(I); -- { dg-bogus "out-of-bounds access" }
Put_Line("Iteration");
end loop;
for I in 0 .. 7 loop
sid := Tg2.Groups(I); -- { dg-warning "out-of-bounds access" }
Put_Line("Iteration");
end loop;
for I in 0 .. N loop
sid := Tg2.Groups(I); -- { dg-warning "out-of-bounds access" }
Put_Line("Iteration");
end loop;
end;
with Interfaces.C; use Interfaces.C;
with System;
package Warn12_Pkg is
Anysize_Array: constant := 0;
type Sid_And_Attributes is record
Sid : System.Address;
Attributes : Interfaces.C.Unsigned_Long;
end record;
type Sid_And_Attributes_Array
is array (Integer range 0..Anysize_Array) of aliased Sid_And_Attributes;
type Token_Groups is record
GroupCount : Interfaces.C.Unsigned_Long;
Groups : Sid_And_Attributes_Array;
end record;
end Warn12_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