A new pragma/aspect, First_Controlling_Parameter, is introduced for tagged
types, altering the semantics of primitive/controlling parameters. When a
tagged type is marked with this aspect, only subprograms where the first
parameter is of that type will be considered dispatching primitives. This
pragma/aspect applies to the entire hierarchy, starting from the specified
type, without affecting inherited primitives.
Here is an example of this feature:
package Example is
type Root is tagged private;
procedure P (V : Integer; V2 : Root);
-- Primitive
type Child is tagged private
with First_Controlling_Parameter;
private
type Root is tagged null record;
type Child is new Root with null record;
overriding
procedure P (V : Integer; V2 : Child);
-- Primitive
procedure P2 (V : Integer; V2 : Child);
-- NOT Primitive
function F return Child; -- NOT Primitive
function F2 (V : Child) return Child;
-- Primitive, but only controlling on the first parameter
end Example;
Note that function F2 (V : Child) return Child; differs from F2 (V : Child)
return Child'Class; in that the return type is a specific, definite type. This
is also distinct from the legacy semantics, where further derivations with
added fields would require overriding the function.
The option -gnatw_j, that you can pass to the compiler directly, enables
warnings related to this new language feature. For instance, compiling the
example above without this switch produces no warnings, but compiling it with
-gnatw_j generates the following warning on the declaration of procedure P2:
warning: not a dispatching primitive of tagged type "Child" warning: disallowed by First_Controlling_Parameter on "Child"
For generic formal tagged types, you can specify whether the type has the First_Controlling_Parameter aspect enabled:
generic
type T is tagged private with First_Controlling_Parameter;
package T is
type U is new T with null record;
function Foo return U; -- Not a primitive
end T;
For tagged partial views, the value of the aspect must be consistent between the partial and full views:
package R is type T is tagged private; ... private type T is tagged null record with First_Controlling_Parameter; -- ILLEGAL end R;
Restricting the position of controlling parameter offers several advantages: