tree-cfg.c (call_can_make_abnormal_goto): New predicate.
* tree-cfg.c (call_can_make_abnormal_goto): New predicate. (stmt_can_make_abnormal_goto): Use it. (is_ctrl_altering_stmt): Likewise. From-SVN: r186047
This commit is contained in:
parent
9a9dcce8e8
commit
8d960eda47
@ -1,3 +1,9 @@
|
||||
2012-03-31 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* tree-cfg.c (call_can_make_abnormal_goto): New predicate.
|
||||
(stmt_can_make_abnormal_goto): Use it.
|
||||
(is_ctrl_altering_stmt): Likewise.
|
||||
|
||||
2012-03-30 Naveen H.S <naveen.S@kpitcummins.com>
|
||||
Kaz Kojima <kkojima@gcc.gnu.org>
|
||||
|
||||
|
@ -1,3 +1,9 @@
|
||||
2012-03-31 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gnat.dg/controlled6.adb: New test.
|
||||
* gnat.dg/controlled6_pkg.ads: New helper.
|
||||
* gnat.dg/controlled6_pkg-iterators.ad[sb]: Likewise.
|
||||
|
||||
2012-03-30 Richard Henderson <rth@redhat.com>
|
||||
|
||||
PR debug/52727
|
||||
|
24
gcc/testsuite/gnat.dg/controlled6.adb
Normal file
24
gcc/testsuite/gnat.dg/controlled6.adb
Normal file
@ -0,0 +1,24 @@
|
||||
-- { dg-do compile }
|
||||
-- { dg-options "-O -gnatn" }
|
||||
|
||||
with Ada.Text_IO; use Ada.Text_IO;
|
||||
with Controlled6_Pkg;
|
||||
with Controlled6_Pkg.Iterators;
|
||||
|
||||
procedure Controlled6 is
|
||||
|
||||
type String_Access is access String;
|
||||
|
||||
package My_Q is new Controlled6_Pkg (String_Access);
|
||||
package My_Iterators is new My_Q.Iterators (0);
|
||||
use My_Iterators;
|
||||
|
||||
Iterator : Iterator_Type := Find;
|
||||
|
||||
begin
|
||||
loop
|
||||
exit when Is_Null (Iterator);
|
||||
Put (Current (Iterator).all & ' ');
|
||||
Find_Next (Iterator);
|
||||
end loop;
|
||||
end;
|
21
gcc/testsuite/gnat.dg/controlled6_pkg-iterators.adb
Normal file
21
gcc/testsuite/gnat.dg/controlled6_pkg-iterators.adb
Normal file
@ -0,0 +1,21 @@
|
||||
package body Controlled6_Pkg.Iterators is
|
||||
|
||||
function Find return Iterator_Type is
|
||||
Iterator : Iterator_Type;
|
||||
begin
|
||||
return Iterator;
|
||||
end Find;
|
||||
|
||||
function Current (Iterator : in Iterator_Type) return T is begin
|
||||
return Iterator.Current.Item;
|
||||
end Current;
|
||||
|
||||
procedure Find_Next (Iterator : in out Iterator_Type) is begin
|
||||
Iterator.Current := null;
|
||||
end Find_Next;
|
||||
|
||||
function Is_Null (Iterator : in Iterator_Type) return Boolean is begin
|
||||
return Iterator.Current = null;
|
||||
end Is_Null;
|
||||
|
||||
end Controlled6_Pkg.Iterators;
|
22
gcc/testsuite/gnat.dg/controlled6_pkg-iterators.ads
Normal file
22
gcc/testsuite/gnat.dg/controlled6_pkg-iterators.ads
Normal file
@ -0,0 +1,22 @@
|
||||
with Ada.Finalization;
|
||||
|
||||
generic
|
||||
|
||||
I : Integer;
|
||||
|
||||
package Controlled6_Pkg.Iterators is
|
||||
|
||||
type Iterator_Type is new Ada.Finalization.Controlled with record
|
||||
Current : Node_Access_Type;
|
||||
end record;
|
||||
|
||||
function Find return Iterator_Type;
|
||||
|
||||
function Current (Iterator : in Iterator_Type) return T;
|
||||
pragma Inline (Current);
|
||||
|
||||
procedure Find_Next (Iterator : in out Iterator_Type);
|
||||
|
||||
function Is_Null (Iterator : in Iterator_Type) return Boolean;
|
||||
|
||||
end Controlled6_Pkg.Iterators;
|
15
gcc/testsuite/gnat.dg/controlled6_pkg.ads
Normal file
15
gcc/testsuite/gnat.dg/controlled6_pkg.ads
Normal file
@ -0,0 +1,15 @@
|
||||
with Ada.Finalization;
|
||||
|
||||
generic
|
||||
|
||||
type T is private;
|
||||
|
||||
package Controlled6_Pkg is
|
||||
|
||||
type Node_Type is record
|
||||
Item : T;
|
||||
end record;
|
||||
|
||||
type Node_Access_Type is access Node_Type;
|
||||
|
||||
end Controlled6_Pkg;
|
@ -2273,6 +2273,43 @@ gimple_cfg2vcg (FILE *file)
|
||||
Miscellaneous helpers
|
||||
---------------------------------------------------------------------------*/
|
||||
|
||||
/* Return true if T, a GIMPLE_CALL, can make an abnormal transfer of control
|
||||
flow. Transfers of control flow associated with EH are excluded. */
|
||||
|
||||
static bool
|
||||
call_can_make_abnormal_goto (gimple t)
|
||||
{
|
||||
/* If the function has no non-local labels, then a call cannot make an
|
||||
abnormal transfer of control. */
|
||||
if (!cfun->has_nonlocal_label)
|
||||
return false;
|
||||
|
||||
/* Likewise if the call has no side effects. */
|
||||
if (!gimple_has_side_effects (t))
|
||||
return false;
|
||||
|
||||
/* Likewise if the called function is leaf. */
|
||||
if (gimple_call_flags (t) & ECF_LEAF)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/* Return true if T can make an abnormal transfer of control flow.
|
||||
Transfers of control flow associated with EH are excluded. */
|
||||
|
||||
bool
|
||||
stmt_can_make_abnormal_goto (gimple t)
|
||||
{
|
||||
if (computed_goto_p (t))
|
||||
return true;
|
||||
if (is_gimple_call (t))
|
||||
return call_can_make_abnormal_goto (t);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Return true if T represents a stmt that always transfers control. */
|
||||
|
||||
bool
|
||||
@ -2306,10 +2343,8 @@ is_ctrl_altering_stmt (gimple t)
|
||||
{
|
||||
int flags = gimple_call_flags (t);
|
||||
|
||||
/* A non-pure/const call alters flow control if the current
|
||||
function has nonlocal labels. */
|
||||
if (!(flags & (ECF_CONST | ECF_PURE | ECF_LEAF))
|
||||
&& cfun->has_nonlocal_label)
|
||||
/* A call alters control flow if it can make an abnormal goto. */
|
||||
if (call_can_make_abnormal_goto (t))
|
||||
return true;
|
||||
|
||||
/* A call also alters control flow if it does not return. */
|
||||
@ -2367,21 +2402,6 @@ simple_goto_p (gimple t)
|
||||
}
|
||||
|
||||
|
||||
/* Return true if T can make an abnormal transfer of control flow.
|
||||
Transfers of control flow associated with EH are excluded. */
|
||||
|
||||
bool
|
||||
stmt_can_make_abnormal_goto (gimple t)
|
||||
{
|
||||
if (computed_goto_p (t))
|
||||
return true;
|
||||
if (is_gimple_call (t))
|
||||
return (gimple_has_side_effects (t) && cfun->has_nonlocal_label
|
||||
&& !(gimple_call_flags (t) & ECF_LEAF));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
/* Return true if STMT should start a new basic block. PREV_STMT is
|
||||
the statement preceding STMT. It is used when STMT is a label or a
|
||||
case label. Labels should only start a new basic block if their
|
||||
|
Loading…
Reference in New Issue
Block a user