6.5.1 Nonreturning SubprogramsPragma No_Return
Discussion: Aspect No_Deposit
will have to wait for Ada
2028 2020.
:-)
Static Semantics
{
AI05-0229-1}
{
AI12-0269-1}
For a
subprogram procedure
or generic
subprogram procedure,
the following language-defined representation aspect may be specified:
No_Return
The type of aspect No_Return is Boolean. When aspect No_Return is True
for an entity, the entity is said to be
nonreturning.
{
AI12-0423-1}
If directly specified, the
aspect_definition
shall be a static expression.
When not directly
specified, if the subprogram is a primitive subprogram inherited by a
derived type, then the aspect is True if any corresponding subprogram
of the parent or progenitor types is nonreturning. Otherwise [This
aspect is never inherited;] if not directly specified, the aspect
is False.
Aspect Description for No_Return:
A subprogram procedure
will not return normally.
{
AI05-0229-1}
{
AI12-0269-1}
If a generic
subprogram procedure
is nonreturning, then so are its instances. If a
subprogram procedure
declared within a generic unit is nonreturning, then so are the corresponding
copies of that
subprogram procedure
in instances.
Legality Rules
Reason: A null procedure cannot have
the appropriate nonreturning semantics, as it does not raise an exception
or loop forever.
Ramification: {
AI05-0229-1}
{
AI12-0269-1}
The procedure can be abstract. If a nonreturning
subprogram procedure
is renamed (anywhere) calls through the new name still have the nonreturning
semantics.
Ramification: We
still require at least one return statement in a function; we just require
that all such return statements don't actually return a value.
{
AI95-00414-01}
{
AI12-0269-1}
A
subprogram procedure
shall be nonreturning if it overrides a dispatching nonreturning
subprogram procedure.
In addition to the places where Legality Rules normally
apply (see
12.3), this rule applies also in
the private part of an instance of a generic unit.
Reason: This ensures that dispatching
calls to nonreturning subprograms procedures
will, in fact, not return.
{
AI95-00414-01}
{
AI12-0269-1}
If a renaming-as-body completes a nonreturning
subprogram procedure
declaration, then the renamed
subprogram procedure
shall be nonreturning.
Reason: This ensures that no extra code
is needed to implement the renames (that is, no wrapper is needed) as
the body has the same property.
Paragraph 8 was deleted.
Dynamic Semantics
{
AI95-00329-01}
{
AI95-00414-01}
If the body of a nonreturning procedure completes normally, Program_Error
is raised at the point of the call.
Discussion: {
AI12-0269-1}
Note that there is no name for suppressing this check, since the check
represents a bug, imposes no time overhead, and minimal space overhead
(since it can usually be statically eliminated as dead code).
We don't need a similar rule for nonreturning functions as this is standard
semantics for all functions that normally complete without a transfer
of control (such as a return statement).
Implementation Note: If a nonreturning
procedure tries to return, we raise Program_Error. This is stated as
happening at the call site, because we do not wish to allow the procedure
to handle the exception (and then, perhaps, try to return again!). However,
the expected run-time model is that the compiler will generate raise
Program_Error at the end of the procedure body (but not handleable by
the procedure itself), as opposed to doing it at the call site. (This
is just like the typical run-time model for functions that fall off the
end without returning a value). The reason is indirect calls: in P.all(...);,
the compiler cannot know whether P designates a nonreturning procedure
or a normal one. Putting the raise Program_Error in the procedure's
generated code solves this problem neatly.
Similarly, if one passes a nonreturning procedure
to a generic formal parameter, the compiler cannot know this at call
sites (in shared code implementations); the raise-in-body solution deals
with this neatly.
Examples
{
AI12-0429-1}
Example of a specification of a No_Return aspect:
{
AI95-00433-01}
{
AI05-0229-1}
procedure Fail(Msg : String) --
raises Fatal_Error exception
with No_Return;
--
Inform compiler and reader that procedure never returns normally
Extensions to Ada 95
Extensions to Ada 2005
Incompatibilities With Ada 2012
{
AI12-0423-1}
Correction: Clarified
that the nonreturning property is inherited by derivation. A literal
implementation of the Ada 2012 would mean that no overriding would ever
be rejected, as the inherited routine would never be nonreturning. Ada
2022 requires overridings of dispatching nonreturning subprograms to
be rejected. This is formally incompatible, but practically such overridings
have been rejected in practice.
Extensions to Ada 2012
{
AI12-0269-1}
Aspect No_Return can now be
applied to functions as well as procedures.
Ada 2005 and 2012 Editions sponsored in part by Ada-Europe