OSDN Git Service

2005-03-08 Javier Miranda <miranda@adacore.com>
[pf3gnuchains/gcc-fork.git] / gcc / ada / checks.ads
index d265ae8..2ec2c16 100644 (file)
@@ -6,9 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---                            $Revision: 1.55 $
---                                                                          --
---          Copyright (C) 1992-2001 Free Software Foundation, Inc.          --
+--          Copyright (C) 1992-2004 Free Software Foundation, Inc.          --
 --                                                                          --
 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
 -- terms of the  GNU General Public License as published  by the Free Soft- --
@@ -22,7 +20,7 @@
 -- MA 02111-1307, USA.                                                      --
 --                                                                          --
 -- GNAT was originally developed  by the GNAT team at  New York University. --
--- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
+-- Extensive contributions were provided by Ada Core Technologies Inc.      --
 --                                                                          --
 ------------------------------------------------------------------------------
 
@@ -73,9 +71,8 @@ package Checks is
    --  operate anyway since they may generate useful compile time warnings.
 
    procedure Apply_Access_Check (N : Node_Id);
-   --  Determines whether an expression node should be flagged as needing
-   --  a runtime access check. If the node requires such a check, the
-   --  Do_Access_Check flag is turned on.
+   --  Determines whether an expression node requires a runtime access
+   --  check and if so inserts the appropriate run-time check.
 
    procedure Apply_Accessibility_Check (N : Node_Id; Typ : Entity_Id);
    --  Given a name N denoting an access parameter, emits a run-time
@@ -83,6 +80,13 @@ package Checks is
    --  the object denoted by the access parameter is not deeper than the
    --  level of the type Typ. Program_Error is raised if the check fails.
 
+   procedure Apply_Alignment_Check (E : Entity_Id; N : Node_Id);
+   --  E is the entity for an object. If there is an address clause for
+   --  this entity, and checks are enabled, then this procedure generates
+   --  a check that the specified address has an alignment consistent with
+   --  the alignment of the object, raising PE if this is not the case. The
+   --  resulting check (if one is generated) is inserted before node N.
+
    procedure Apply_Array_Size_Check (N : Node_Id; Typ : Entity_Id);
    --  N is the node for an object declaration that declares an object of
    --  array type Typ. This routine generates, if necessary, a check that
@@ -166,6 +170,81 @@ package Checks is
    --  Thus the significance of OK being False on return is that no
    --  useful information is available on the range of the expression.
 
+   -------------------------------------------------------
+   -- Control and Optimization of Range/Overflow Checks --
+   -------------------------------------------------------
+
+   --  Range checks are controlled by the Do_Range_Check flag. The front end
+   --  is responsible for setting this flag in relevant nodes. Originally
+   --  the back end generated all corresponding range checks. But later on
+   --  we decided to generate all range checks in the front end. We are now
+   --  in the transitional phase where some of these checks are still done
+   --  by the back end, but many are done by the front end.
+
+   --  Overflow checks are similarly controlled by the Do_Overflow_Check
+   --  flag. The difference here is that if Backend_Overflow_Checks is
+   --  is (Backend_Overflow_Checks_On_Target set False), then the actual
+   --  overflow checks are generated by the front end, but if back end
+   --  overflow checks are active (Backend_Overflow_Checks_On_Target
+   --  set True), then the back end does generate the checks.
+
+   --  The following two routines are used to set these flags, they allow
+   --  for the possibility of eliminating checks. Checks can be eliminated
+   --  if an identical check has already been performed.
+
+   procedure Enable_Overflow_Check (N : Node_Id);
+   --  First this routine determines if an overflow check is needed by doing
+   --  an appropriate range check. If a check is not needed, then the call
+   --  has no effect. If a check is needed then this routine sets the flag
+   --  Set Do_Overflow_Check in node N to True, unless it can be determined
+   --  that the check is not needed. The only condition under which this is
+   --  the case is if there was an identical check earlier on.
+
+   procedure Enable_Range_Check (N : Node_Id);
+   --  Set Do_Range_Check flag in node N True, unless it can be determined
+   --  that the check is not needed. The only condition under which this is
+   --  the case is if there was an identical check earlier on. This routine
+   --  is not responsible for doing range analysis to determine whether or
+   --  not such a check is needed -- the caller is expected to do this. The
+   --  one other case in which the request to set the flag is ignored is
+   --  when Kill_Range_Check is set in an N_Unchecked_Conversion node.
+
+   --  The following routines are used to keep track of processing sequences
+   --  of statements (e.g. the THEN statements of an IF statement). A check
+   --  that appears within such a sequence can eliminate an identical check
+   --  within this sequence of statements. However, after the end of the
+   --  sequence of statements, such a check is no longer of interest, since
+   --  it may not have been executed.
+
+   procedure Conditional_Statements_Begin;
+   --  This call marks the start of processing of a sequence of statements.
+   --  Every call to this procedure must be followed by a matching call to
+   --  Conditional_Statements_End.
+
+   procedure Conditional_Statements_End;
+   --  This call removes from consideration all saved checks since the
+   --  corresponding call to Conditional_Statements_Begin. These two
+   --  procedures operate in a stack like manner.
+
+   --  The mechanism for optimizing checks works by remembering checks
+   --  that have already been made, but certain conditions, for example
+   --  an assignment to a variable involved in a check, may mean that the
+   --  remembered check is no longer valid, in the sense that if the same
+   --  expression appears again, another check is required because the
+   --  value may have changed.
+
+   --  The following routines are used to note conditions which may render
+   --  some or all of the stored and remembered checks to be invalidated.
+
+   procedure Kill_Checks (V : Entity_Id);
+   --  This procedure records an assignment or other condition that causes
+   --  the value of the variable to be changed, invalidating any stored
+   --  checks that reference the value. Note that all such checks must
+   --  be discarded, even if they are not in the current statement range.
+
+   procedure Kill_All_Checks;
+   --  This procedure kills all remembered checks.
+
    -----------------------------
    -- Length and Range Checks --
    -----------------------------
@@ -288,12 +367,6 @@ package Checks is
    --  flag. Checks_On is a boolean value that says if range and index checking
    --  is on or not.
 
-   procedure Enable_Range_Check (N : Node_Id);
-   pragma Inline (Enable_Range_Check);
-   --  Set Do_Range_Check flag in node N to True unless Kill_Range_Check flag
-   --  is set in N (the purpose of the latter flag is precisely to prevent
-   --  Do_Range_Check from being set).
-
    procedure Insert_Range_Checks
      (Checks       : Check_Result;
       Node         : Node_Id;
@@ -326,12 +399,65 @@ package Checks is
    --  in constructing the check.
 
    -----------------------
+   -- Expander Routines --
+   -----------------------
+
+   --  Some of the earlier processing for checks results in temporarily
+   --  setting the Do_Range_Check flag rather than actually generating
+   --  checks. Now we are moving the generation of such checks into the
+   --  front end for reasons of efficiency and simplicity (there were
+   --  difficutlies in handling this in the back end when side effects
+   --  were present in the expressions being checked).
+
+   --  Probably we could eliminate the Do_Range_Check flag entirely and
+   --  generate the checks earlier, but this is a delicate area and it
+   --  seemed safer to implement the following routines, which are called
+   --  late on in the expansion process. They check the Do_Range_Check flag
+   --  and if it is set, generate the actual checks and reset the flag.
+
+   procedure Generate_Range_Check
+     (N           : Node_Id;
+      Target_Type : Entity_Id;
+      Reason      : RT_Exception_Code);
+   --  This procedure is called to actually generate and insert a range
+   --  check. A check is generated to ensure that the value of N lies
+   --  within the range of the target type. Note that the base type of
+   --  N may be different from the base type of the target type. This
+   --  happens in the conversion case. The Reason parameter is the
+   --  exception code to be used for the exception if raised.
+   --
+   --  Note on the relation of this routine to the Do_Range_Check flag.
+   --  Mostly for historical reasons, we often set the Do_Range_Check
+   --  flag and then later we call Generate_Range_Check if this flag is
+   --  set. Most probably we could eliminate this intermediate setting
+   --  of the flag (historically the back end dealt with range checks,
+   --  using this flag to indicate if a check was required, then we
+   --  moved checks into the front end).
+
+   procedure Generate_Index_Checks (N : Node_Id);
+   --  This procedure is called to generate index checks on the subscripts
+   --  for the indexed component node N. Each subscript expression is
+   --  examined, and if the Do_Range_Check flag is set, an appropriate
+   --  index check is generated and the flag is reset.
+
+   --  Similarly, we set the flag Do_Discriminant_Check in the semantic
+   --  analysis to indicate that a discriminant check is required for a
+   --  selected component of a discriminated type. The following routine
+   --  is called from the expander to actually generate the call.
+
+   procedure Generate_Discriminant_Check (N : Node_Id);
+   --  N is a selected component for which a discriminant check is required
+   --  to make sure that the discriminants have appropriate values for the
+   --  selection. This is done by calling the appropriate discriminant
+   --  checking routine for the selector.
+
+   -----------------------
    -- Validity Checking --
    -----------------------
 
    --  In (RM 13.9.1(9-11)) we have the following rules on invalid values
 
-   --    9   If the representation of a scalar object does not represent a
+   --    If the representation of a scalar object does not represent a
    --    value of the object's subtype (perhaps because the object was not
    --    initialized), the object is said to have an invalid representation.
    --    It is a bounded error to evaluate the value of such an object.  If
@@ -490,6 +616,14 @@ package Checks is
    --  the sense of the 'Valid attribute returning True. Constraint_Error
    --  will be raised if the value is not valid.
 
+   procedure Null_Exclusion_Static_Checks (N : Node_Id);
+   --  Ada 2005 (AI-231): Check bad usages of the null-exclusion issue
+
+   procedure Remove_Checks (Expr : Node_Id);
+   --  Remove all checks from Expr except those that are only executed
+   --  conditionally (on the right side of And Then/Or Else. This call
+   --  removes only embedded checks (Do_Range_Check, Do_Overflow_Check).
+
 private
 
    type Check_Result is array (Positive range 1 .. 2) of Node_Id;
@@ -508,18 +642,6 @@ private
    --  For external clients, the required processing on this result is
    --  achieved using the Insert_Range_Checks routine.
 
-   pragma Inline (Access_Checks_Suppressed);
-   pragma Inline (Accessibility_Checks_Suppressed);
-   pragma Inline (Discriminant_Checks_Suppressed);
-   pragma Inline (Division_Checks_Suppressed);
-   pragma Inline (Elaboration_Checks_Suppressed);
-   pragma Inline (Index_Checks_Suppressed);
-   pragma Inline (Length_Checks_Suppressed);
-   pragma Inline (Overflow_Checks_Suppressed);
-   pragma Inline (Range_Checks_Suppressed);
-   pragma Inline (Storage_Checks_Suppressed);
-   pragma Inline (Tag_Checks_Suppressed);
-
    pragma Inline (Apply_Length_Check);
    pragma Inline (Apply_Range_Check);
    pragma Inline (Apply_Static_Length_Check);