6.5.1 Nonreturning Subprograms
Discussion: Aspect No_Deposit
will have to wait for Ada 2028. :-)
Static Semantics
{
AI05-0229-1}
{
AI12-0269-1}
For a subprogram or generic subprogram, 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, the aspect is False.
Aspect Description for No_Return:
A subprogram will not return normally.
{
AI05-0229-1}
{
AI12-0269-1}
If a generic subprogram is nonreturning, then so are its instances. If
a subprogram declared within a generic unit is nonreturning, then so
are the corresponding copies of that subprogram 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 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 shall be nonreturning if it overrides a dispatching nonreturning
subprogram.
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 will, in fact, not return.
{
AI95-00414-01}
{
AI12-0269-1}
If a renaming-as-body completes a nonreturning subprogram declaration,
then the renamed subprogram 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