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:
Eric Botcazou 2012-03-31 17:21:01 +00:00 committed by Eric Botcazou
parent 9a9dcce8e8
commit 8d960eda47
7 changed files with 133 additions and 19 deletions

View File

@ -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>

View File

@ -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

View 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;

View 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;

View 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;

View 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;

View File

@ -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