Annotated Ada Reference Manual (Ada 202y Draft 3)Legal Information
Contents   Index   References   Search   Previous   Next 

6.5.1 Nonreturning Subprograms

1/5
{AI95-00329-01} {AI95-00414-01} {AI05-0229-1} {AI12-0269-1} {AI12-0418-1} Specifying aspect No_Return to have the value True indicates that a subprogram cannot return normally[; it may, for example, propagate an exception or loop forever]. 
1.a/5
Discussion: Aspect No_Deposit will have to wait for Ada 2028. :-) 
Paragraphs 2 and 3 were moved to Annex J, “Obsolescent Features”. 

Static Semantics

3.1/6
 {AI05-0229-1} {AI12-0269-1} {AI22-0090-1} For a subprogram (including a generic formal subprogram), an access-to-subprogram type (including a formal access-to-subprogram type), or a generic subprogram, the following language-defined representation aspect may be specified: 
3.2/3
 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.
3.3/5
{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.
3.4/6
{AI22-0090-1} The No_Return aspect of a dereference of a value of an access-to-subprogram type is the same as that of the type.
3.a/5
Aspect Description for No_Return: A subprogram will not return normally.
3.5/6
 {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

4/6
{AI95-00329-01} {AI95-00414-01} {AI05-0229-1} {AI12-0093-1} A subprogram defined by a null_procedure_declaration Aspect No_Return shall not be nonreturning specified for. For an instance of a generic subprogram, any specification of aspect No_Return shall be confirming a null procedure nor an instance of a generic unit.
4.a/6
Reason: {AI12-0093-1} A null procedure cannot have the appropriate nonreturning semantics, as it does not raise an exception or loop forever. Therefore, we do not allow the aspect No_Return to be specified True on a null procedure, nor can a null_procedure_declaration complete a procedure that has aspect No_Return specified True. Generic instances always inherit whether or not they are nonreturning from the generic unit. Thus we only allow writing a confirming aspect specification. 
4.b/6
Ramification: {AI12-0093-1} {AI05-0229-1} {AI12-0269-1} {AI22-0005-1} The procedure can be abstract. If a nonreturning subprogram is renamed (anywhere), calls through the new name still have the nonreturning semantics. 
5/2
{AI95-00329-01} {AI95-00414-01} A return statement shall not apply to a nonreturning procedure or generic procedure.
5.1/6
 {AI12-0269-1} {AI22-0093-1} An extended_return_statement shall not apply to a nonreturning function or generic function. Any return expression of statement that applies to a nonreturning function or generic function shall be a simple_return_statement with an expression that is a raise_expression, a call on a nonreturning function, or a parenthesized expression expression of one of these.
5.a/5
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. 
6/5
{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.
6.a/5
Reason: This ensures that dispatching calls to nonreturning subprograms will, in fact, not return. 
7/5
{AI95-00414-01} {AI12-0269-1} If a renaming-as-body completes a nonreturning subprogram declaration, then the renamed subprogram shall be nonreturning.
7.a/2
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. 
7.1/6
 {AI22-0090-1} If a No_Return aspect is True for a generic formal subprogram or a generic formal access-to-subprogram type, it shall be True for the matching actual in an instantiation.
7.2/6
 {AI22-0090-1} If a No_Return aspect is True for an access-to-subprogram type T, then it shall be True for a subprogram S if S'Access has an expected type of T. Similarly, on a conversion to such a type, the No_Return aspect shall be true for the operand type.
Paragraph 8 was deleted.

Dynamic Semantics

9/2
{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.
9.a/5
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). 
9.b/2
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.
9.c/2
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

10/5
{AI12-0429-1} Example of a specification of a No_Return aspect: 
11/3
{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

11.a/2
{AI95-00329-01} {AI95-00414-01} Pragma No_Return is new. 

Extensions to Ada 2005

11.b/3
{AI05-0229-1} Aspect No_Return is new; pragma No_Return is now obsolescent. 

Incompatibilities With Ada 2012

11.c/5
{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

11.d/5
{AI12-0269-1} Aspect No_Return can now be applied to functions as well as procedures. 

Incompatibilities With Ada 2022

11.e/6
{AI22-0093-1} Corrigendum: Adjust the rules so that a null_procedure_declaration is not allowed to complete a nonreturning procedure declaration. This was allowed in Ada 2012 and original Ada 2022, but calling such a routine would always raise Program_Error. So it is unlikely that any such code exists.
11.f/6
{AI22-0093-1} Corrigendum: Clarified that the restrictions on what a nonreturning function can return apply to the expression of a nonreturning expression_function_declaration as well. This is formally an incompatibility, but it seems so obvious that it is likely that most implementations already enforce the rules. Thus the incompatibility is highly unlikely to appear in existing code.

Extensions to Ada 2022

11.g/6
{AI22-0090-1} Corrigendum: We now support the aspect No_Return on generic formal subprograms and on access-to-subprogram types. The matching/referenced subprogram must be nonreturning if the formal/type in nonreturning.
11.h/6
{AI22-0093-1} Corrigendum: We now allow specifying confirming values of aspect No_Return on null procedures and generic subprogram instances. This can provide valuable documentation. 

Contents   Index   References   Search   Previous   Next 
Ada-Europe Ada 2005 and 2012 Editions sponsored in part by Ada-Europe