Rationale for Ada 2012

John Barnes
Contents   Index   References   Search   Previous   Next 

6.5 Restrictions

Restrictions provide a valuable way of increasing security. Ada is a rich language and even richer with Ada 2012 and although individual features are straightforward, certain combinations can cause problems.
The new restrictions introduced into Ada 2012 have already been described in this or earlier chapters such as the Introduction (see 1.3.5). However, for convenience here is a complete list giving the annex where appropriate.
The new Restrictions identifiers are
No_Access_Parameter_Allocators    High-Integrity
No_Anonymous_Allocators    High-Integrity
No_Coextensions    High-Integrity
No_Implementation_Aspect_Specifications
No_Implementation_Identifiers
No_Implementation_Units
No_Specification_Of_Aspect
No_Standard_Allocators_After_Elaboration    Real-Time
No_Use_Of_Attribute
No_Use_Of_Pragma
Some of the new Restrictions identifiers are in the High-Integrity annex. They are
pragma Restrictions(No_Access_Parameter_Allocators);
pragma Restrictions(No_Anonymous_Allocators);
pragma Restrictions(No_Coextensions);
and these were discussed in the previous section.
In a similar vein there is one new restriction in the Real-Time annex, namely
pragma Restrictions(No_Standard_Allocators_After_Elaboration);
and this was also discussed in the previous section.
A number of restrictions prevent the use of implementation-defined features. They are
pragma Restrictions(No_Implementation_Aspect_Specifications);
pragma Restrictions(No_Implementation_Identifiers);
pragma Restrictions(No_Implementation_Units);
These do not apply to the whole partition but only to the compilation or environment concerned. This helps us to ensure that implementation dependent areas of a program are identified. They were discussed in the Introduction (see 1.3.5) and join similar restrictions No_Implementation_Attributes and No_Implementation_Pragmas introduced in Ada 2005.
The restrictions on implementation-defined aspect specifications, attributes and pragmas are obvious but some clarification of what is meant by the restrictions on units and identifiers might be helpful.
It will be recalled that the predefined packages are Ada, System and Interfaces plus various children. In the so-called standard mode, implementations are not permitted to add their own child packages of Ada but can add grandchildren. Thus an implementation might add an additional container package called perhaps Ada.Containers.Slopbucket. If a program were to use this grandchild then clearly it would be unlikely to be portable to other implementations. Accordingly, giving the restriction No_Implementation_Units prevents such potential difficulties. Similarly, this restriction prevents the use of implementation-defined child units of System and Interfaces.
The restriction No_Implementation_Identifiers is more subtle. It will be recalled that several predefined packages are permitted to add implementation-defined identifiers. They are
Standard,
System,
Ada.Command_Line,
Interfaces.C,
Interfaces.C.Strings,
Interfaces.C.Pointers,
Interfaces.COBOL,
and Interfaces.Fortran.
Moreover, the following predefined packages only contain implementation-defined identifiers
Interfaces,
System.Machine_Code,
Ada.Directories.Information,
Ada.Directories.Names,
and the packages Implementation nested in the queue containers.
The restriction No_Implementation_Identifiers prevents the use of any of these.
There is a slight subtlety regarding Long_Integer and Long_Float in Standard. The types Integer and Float must be provided. Types such as Short_Integer and Long_Long_Float may be provided but are definitely considered to be implementation-defined and so excluded by the restriction on implementation identifiers. However, Long_Integer and Long_Float should be provided (if the hardware is capable) and so are considered to be predefined and not covered by the restriction. Nevertheless, an implementation on a specialized small machine might not provide them.
Finally, there are restrictions preventing the use of particular facilities
pragma Restrictions(No_Specification_Of_Aspect => X);
pragma Restrictions(No_Use_Of_Attribute => X);
pragma Restrictions(No_Use_Of_Pragma => X);
where X is the name of a specific aspect, attribute or pragma respectively. They are similar to the restriction No_Dependence introduced in Ada 2005. They apply to a complete partition.
Note that No_Specification_Of_Aspect prevents the specification of an aspect by any means. Remember that some aspects can be specified by an aspect specification or by a pragma or by an attribute definition clause. Thus we mentioned above that a storage pool could be given by an attribute definition clause thus
type Cell_Ptr is access Cell;
for Cell_Ptr'Storage_Pool use Cell_Ptr_Pool;
or by using an aspect specification thus
type Cell_Ptr is access Cell
   with Storage_Pool => Cell_Ptr_Pool;
Writing
pragma Restrictions(No_Specification_Of_Aspect => Storage_Pool);
prevents both of these whereas
pragma Restrictions(No_Use_Of_Attribute => Strorage_Pool);
prevents only the first. Naturally, No_Use_Of_Attribute prevents both setting an attribute and reading it whereas No_Specification_Of_Aspect prevents just setting it. Thus we might want to read 'Size but prevent setting it.
Similarly
pragma Restrictions(No_Specification_Of_Aspect => Pack);
prevents both
type Flags is array (1 .. 8) of Boolean
   with Pack;
and
type Flags is array (1 .. 8) of Boolean;
pragma Pack(Flags);
whereas
pragma Restrictions(No_Use_Of_Pragma => Pack);
prevents only the latter.
In summary, No_Specification_Of_Aspect does not mean No_Aspect_Specification (which does not exist).
Remember that several restrictions can be given in one pragma, so we might have
pragma Restrictions(No_Use_Of_Pragma => P,
                                  No_Use_Of_Attribute  => A);
As mentioned in the Introduction (see 1.3.5) there is also a new profile No_Implementation_Extensions. This is specified by
pragma Profile(No_Implementation_Extensions);
and is equivalent to writing
pragma Restrictions(
   No_Implementation_Aspect_Specifications,
   No_Implementation_Attributes,
   No_Implementation_Identifiers,
   No_Implementation_Pragmas,
   No_Implementation_Units);
thus providing blanket security against writing programs that use language extensions. This profile is defined in the core language. The only other profile defined in Ada 2012 is Ravenscar which was introduced in Ada 2005 and is in the Real-Time systems annex. Remember that the pragma Profile is a configuration pragma.
Finally, those of a recursive nature might note that writing
pragma Restrictions(No_Use_Of_Pragma => Restrictions);
is illegal (this prevents the risk that the compiler might melt down). More curiously, there is not a restriction No_Implementation_Restrictions. This might be because of similar concern regarding what would happen with its recursive use.

Contents   Index   References   Search   Previous   Next 
© 2011, 2012, 2013 John Barnes Informatics.
Sponsored in part by:
The Ada Resource Association:

    ARA
  AdaCore:


    AdaCore
and   Ada-Europe:

Ada-Europe