when Attribute_To_Address => To_Address : declare
Val : Uint;
-
begin
Check_E1;
Analyze (P);
Generate_Reference (RTE (RE_Address), P);
Analyze_And_Resolve (E1, Any_Integer);
Set_Etype (N, RTE (RE_Address));
-
- if Is_Static_Expression (E1) then
- Set_Is_Static_Expression (N, True);
- end if;
+ Set_Is_Static_Expression (N, Is_Static_Expression (E1));
-- OK static expression case, check range and set appropriate type
Set_Etype (E1, Standard_Unsigned_64);
end if;
end if;
-
- Set_Is_Static_Expression (N, True);
end To_Address;
------------
P_Root_Type : Entity_Id;
-- The root type of the prefix type
- Static : Boolean;
+ Static : Boolean := False;
-- True if the result is Static. This is set by the general processing
-- to true if the prefix is static, and all expressions are static. It
-- can be reset as processing continues for particular attributes. This
-- Start of processing for Eval_Attribute
begin
+ -- The To_Address attribute can be static, but it cannot be evaluated at
+ -- compile time, so just return.
+
+ if Id = Attribute_To_Address then
+ return;
+ end if;
+
-- Initialize result as non-static, will be reset if appropriate
Set_Is_Static_Expression (N, False);
- Static := False;
-- Acquire first two expressions (at the moment, no attributes take more
-- than two expressions in any case).
-- static attribute in GNAT.
Analyze_And_Resolve (N, Standard_Boolean);
- Static := True;
- Set_Is_Static_Expression (N, True);
+ Static := True;
+ Set_Is_Static_Expression (N, True);
end Atomic_Always_Lock_Free;
---------
-- attribute reference, and this reference is not static.
Set_Is_Static_Expression (N, False);
- null;
---------------
-- Copy_Sign --
-- static attribute in GNAT.
Analyze_And_Resolve (N, Standard_Boolean);
- Static := True;
- Set_Is_Static_Expression (N, True);
+ Static := True;
+ Set_Is_Static_Expression (N, True);
end Lock_Free;
----------
-- a subexpression is resolved and is therefore accomplished in a bottom
-- up fashion. The flags are synthesized using the following approach.
- -- Is_Static_Expression is determined by following the detailed rules
- -- in RM 4.9(4-14). This involves testing the Is_Static_Expression
- -- flag of the operands in many cases.
-
- -- Raises_Constraint_Error is set if any of the operands have the flag
- -- set or if an attempt to compute the value of the current expression
- -- results in detection of a runtime constraint error.
-
- -- As described in the spec, the requirement is that Is_Static_Expression
- -- be accurately set, and in addition for nodes for which this flag is set,
- -- Raises_Constraint_Error must also be set. Furthermore a node which has
- -- Is_Static_Expression set, and Raises_Constraint_Error clear, then the
- -- requirement is that the expression value must be precomputed, and the
- -- node is either a literal, or the name of a constant entity whose value
- -- is a static expression.
+ -- Is_Static_Expression is determined by following the rules in
+ -- RM-4.9. This involves testing the Is_Static_Expression flag of
+ -- the operands in many cases.
+
+ -- Raises_Constraint_Error is usually set if any of the operands have
+ -- the flag set or if an attempt to compute the value of the current
+ -- expression results in Constraint_Error.
-- The general approach is as follows. First compute Is_Static_Expression.
-- If the node is not static, then the flag is left off in the node and
-- we are all done. Otherwise for a static node, we test if any of the
- -- operands will raise constraint error, and if so, propagate the flag
+ -- operands will raise Constraint_Error, and if so, propagate the flag
-- Raises_Constraint_Error to the result node and we are done (since the
-- error was already posted at a lower level).
-- For the case of a static node whose operands do not raise constraint
-- error, we attempt to evaluate the node. If this evaluation succeeds,
-- then the node is replaced by the result of this computation. If the
- -- evaluation raises constraint error, then we rewrite the node with
+ -- evaluation raises Constraint_Error, then we rewrite the node with
-- Apply_Compile_Time_Constraint_Error to raise the exception and also
-- to post appropriate error messages.
-- discrete types (the most common case), and is populated by calls to
-- Compile_Time_Known_Value and Expr_Value, but only used by Expr_Value
-- since it is possible for the status to change (in particular it is
- -- possible for a node to get replaced by a constraint error node).
+ -- possible for a node to get replaced by a Constraint_Error node).
CV_Bits : constant := 5;
-- Number of low order bits of Node_Id value used to reference entries
-- If either operand is Any_Type then propagate it to result to prevent
-- cascaded errors.
--
- -- If some operand raises constraint error, then replace the node N
- -- with the raise constraint error node. This replacement inherits the
+ -- If some operand raises Constraint_Error, then replace the node N
+ -- with the raise Constraint_Error node. This replacement inherits the
-- Is_Static_Expression flag from the operands.
procedure Test_Expression_Is_Foldable
return Unknown;
end if;
- -- If either operand could raise constraint error, then we cannot
+ -- If either operand could raise Constraint_Error, then we cannot
-- know the result at compile time (since CE may be raised).
if not (Cannot_Raise_Constraint_Error (L)
CV_Ent : CV_Entry renames CV_Cache (Nat (Op) mod CV_Cache_Size);
begin
- -- Never known at compile time if bad type or raises constraint error
+ -- Never known at compile time if bad type or raises Constraint_Error
-- or empty (latter case occurs only as a result of a previous error).
if No (Op) then
end if;
-- First loop, make sure all the alternatives are static expressions
- -- none of which raise Constraint_Error. We make the constraint error
+ -- none of which raise Constraint_Error. We make the Constraint_Error
-- check because part of the legality condition for a correct static
-- case expression is that the cases are covered, like any other case
-- expression. And we can't do that if any of the conditions raise an
Set_Is_Static_Expression (N);
- -- Now to deal with propagating a possible constraint error
+ -- Now to deal with propagating a possible Constraint_Error
-- If the selecting expression raises CE, propagate and we are done
begin
-- Enumeration literals are always considered to be constants
- -- and cannot raise constraint error (RM 4.9(22)).
+ -- and cannot raise Constraint_Error (RM 4.9(22)).
if Ekind (Def_Id) = E_Enumeration_Literal then
Set_Is_Static_Expression (N);
return;
end if;
- -- If condition raises constraint error then we have already signaled
+ -- If condition raises Constraint_Error then we have already signaled
-- an error, and we just propagate to the result and do not fold.
if Raises_Constraint_Error (Condition) then
end if;
-- Note that it does not matter if the non-result operand raises a
- -- Constraint_Error, but if the result raises constraint error then we
- -- replace the node with a raise constraint error. This will properly
+ -- Constraint_Error, but if the result raises Constraint_Error then we
+ -- replace the node with a raise Constraint_Error. This will properly
-- propagate Raises_Constraint_Error since this flag is set in Result.
if Raises_Constraint_Error (Result) then
Set_Is_Static_Expression (N);
- -- If left operand raises constraint error, propagate and we are done
+ -- If left operand raises Constraint_Error, propagate and we are done
if Raises_Constraint_Error (Expr) then
Set_Raises_Constraint_Error (N, True);
if not Fold then
return;
- -- Don't try fold if target type has constraint error bounds
+ -- Don't try fold if target type has Constraint_Error bounds
elsif not Is_OK_Static_Subtype (Target_Type) then
Set_Raises_Constraint_Error (N);
-- Now look at the operands, we can't quite use the normal call to
-- Test_Expression_Is_Foldable here because short circuit operations
-- are a special case, they can still be foldable, even if the right
- -- operand raises constraint error.
+ -- operand raises Constraint_Error.
-- If either operand is Any_Type, just propagate to result and do not
-- try to fold, this prevents cascaded errors.
Set_Etype (N, Any_Type);
return;
- -- If left operand raises constraint error, then replace node N with
- -- the raise constraint error node, and we are obviously not foldable.
+ -- If left operand raises Constraint_Error, then replace node N with
+ -- the raise Constraint_Error node, and we are obviously not foldable.
-- Is_Static_Expression is set from the two operands in the normal way,
-- and we check the right operand if it is in a non-static context.
-- Here the result is static, note that, unlike the normal processing
-- in Test_Expression_Is_Foldable, we did *not* check above to see if
- -- the right operand raises constraint error, that's because it is not
+ -- the right operand raises Constraint_Error, that's because it is not
-- significant if the left operand is decisive.
Set_Is_Static_Expression (N);
- -- It does not matter if the right operand raises constraint error if
+ -- It does not matter if the right operand raises Constraint_Error if
-- it will not be evaluated. So deal specially with the cases where
-- the right operand is not evaluated. Note that we will fold these
-- cases even if the right operand is non-static, which is fine, but
end if;
-- If first operand not decisive, then it does matter if the right
- -- operand raises constraint error, since it will be evaluated, so
+ -- operand raises Constraint_Error, since it will be evaluated, so
-- we simply replace the node with the right operand. Note that this
-- properly propagates Is_Static_Expression and Raises_Constraint_Error
-- (both are set to True in Right).
if not Fold then
return;
- -- Don't try fold if target type has constraint error bounds
+ -- Don't try fold if target type has Constraint_Error bounds
elsif not Is_OK_Static_Subtype (Target_Type) then
Set_Raises_Constraint_Error (N);
--------------------------
-- Determines if Typ is a static subtype as defined in (RM 4.9(26)) where
- -- neither bound raises constraint error when evaluated.
+ -- neither bound raises Constraint_Error when evaluated.
function Is_OK_Static_Subtype (Typ : Entity_Id) return Boolean is
Base_T : constant Entity_Id := Base_Type (Typ);
then
return False;
- -- If either expression raised a constraint error,
+ -- If either expression raised a Constraint_Error,
-- consider the expressions as matching, since this
-- helps to prevent cascading errors.
Set_Etype (N, Any_Type);
return;
- -- If operand raises constraint error, then replace node N with the
- -- raise constraint error node, and we are obviously not foldable.
+ -- If operand raises Constraint_Error, then replace node N with the
+ -- raise Constraint_Error node, and we are obviously not foldable.
-- Note that this replacement inherits the Is_Static_Expression flag
-- from the operand.
return;
-- Here we have the case of an operand whose type is OK, which is
- -- static, and which does not raise constraint error, we can fold.
+ -- static, and which does not raise Constraint_Error, we can fold.
else
Set_Is_Static_Expression (N);
Set_Etype (N, Any_Type);
return;
- -- If left operand raises constraint error, then replace node N with the
+ -- If left operand raises Constraint_Error, then replace node N with the
-- Raise_Constraint_Error node, and we are obviously not foldable.
-- Is_Static_Expression is set from the two operands in the normal way,
-- and we check the right operand if it is in a non-static context.
return;
-- Else result is static and foldable. Both operands are static, and
- -- neither raises constraint error, so we can definitely fold.
+ -- neither raises Constraint_Error, so we can definitely fold.
else
Set_Is_Static_Expression (N);
if Error_Posted (N) then
return Unknown;
- -- Expression that raises constraint error is an odd case. We certainly
+ -- Expression that raises Constraint_Error is an odd case. We certainly
-- do not want to consider it to be in range. It might make sense to
-- consider it always out of range, but this causes incorrect error
-- messages about static expressions out of range. So we just return
return;
end if;
- -- Test for constraint error raised
+ -- Test for Constraint_Error raised
if Raises_Constraint_Error (Expr) then
-- Is_Static_Expression
- -- This flag is set on any expression that is static according to the
- -- rules in (RM 4.9(3-32)). This flag should be tested during testing
- -- of legality of parts of a larger static expression. For all other
- -- contexts that require static expressions, use the separate predicate
- -- Is_OK_Static_Expression, since an expression that meets the RM 4.9
- -- requirements, but raises a constraint error when evaluated in a non-
- -- static context does not meet the legality requirements.
+ -- True for static expressions, as defined in RM-4.9.
-- Raises_Constraint_Error
-- (i.e. the flag is accurate for static expressions, and conservative
-- for non-static expressions.
- -- If a static expression does not raise constraint error, then it will
- -- have the flag Raises_Constraint_Error flag False, and the expression
- -- must be computed at compile time, which means that it has the form of
- -- either a literal, or a constant that is itself (recursively) either a
- -- literal or a constant.
+ -- See also Is_OK_Static_Expression, which is True for static
+ -- expressions that do not raise Constraint_Error. This is used in most
+ -- legality checks, because static expressions that raise Constraint_Error
+ -- are usually illegal.
- -- The above rules must be followed exactly in order for legality checks to
- -- be accurate. For subexpressions that are not static according to the RM
- -- definition, they are sometimes folded anyway, but of course in this case
- -- Is_Static_Expression is not set.
+ -- See also Compile_Time_Known_Value, which is True for an expression whose
+ -- value is known at compile time. In this case, the expression is folded
+ -- to a literal or to a constant that is itself (recursively) either a
+ -- literal or a constant
+
+ -- Is_[OK_]Static_Expression are used for legality checks, whereas
+ -- Compile_Time_Known_Value is used for optimization purposes.
-- When we are analyzing and evaluating static expressions, we propagate
- -- both flags accurately. Usually if a subexpression raises a constraint
- -- error, then so will its parent expression, and Raise_Constraint_Error
- -- will be propagated to this parent. The exception is conditional cases
- -- like (True or else 1/0 = 0) which results in an expresion that has the
+ -- both flags. Usually if a subexpression raises a Constraint_Error, then
+ -- so will its parent expression, and Raise_Constraint_Error will be
+ -- propagated to this parent. The exception is conditional cases like
+ -- (True or else 1/0 = 0), which results in an expression that has the
-- Is_Static_Expression flag True, and Raises_Constraint_Error False. Even
-- though 1/0 would raise an exception, the right operand is never actually
-- executed, so the expression as a whole does not raise CE.
- -- For constructs in the language where static expressions are part of the
- -- required semantics, we need an expression that meets the 4.9 rules and
- -- does not raise CE. So nearly everywhere, callers should call function
- -- Is_OK_Static_Expression rather than Is_Static_Expression.
-
-- Finally, the case of static predicates. These are applied only to entire
-- expressions, not to subexpressions, so we do not have the case of having
-- to propagate this information. We handle this case simply by resetting