Skip to content

Commit 99ea89d

Browse files
committed
Fix instrumentation of the "next part" of primitive expression functions
When the completion of an expression function is not directly in a package spec declarative part, it is possible to create the augmented expression function in the same scope.
1 parent 4d66db3 commit 99ea89d

File tree

4 files changed

+66
-2
lines changed

4 files changed

+66
-2
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
pragma Ada_2012;
2+
3+
package body Pak is
4+
5+
type BT is tagged record
6+
X : Integer;
7+
end record;
8+
9+
function Make (Cond : Boolean) return BT
10+
is (BT'(X => (if Cond then 1 else 2)));
11+
12+
type BTT is new BT with record
13+
Y : Integer;
14+
end record;
15+
16+
function Make (Cond : Boolean) return BTT
17+
is (BTT'(X => 3, Y => 4));
18+
19+
function Exercise_BT (Cond : Boolean) return Integer
20+
is (BT'(Make (Cond)).X);
21+
22+
function Exercise_BTT (Cond : Boolean) return Integer
23+
is (BTT'(Make (Cond)).Y);
24+
25+
end Pak;

testsuite/tests/instr-cov/expr_func/completion/pak.ads

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ package Pak is
66

77
function Make (Cond : Boolean) return T;
88

9+
function Exercise_BT (Cond : Boolean) return Integer;
10+
function Exercise_BTT (Cond : Boolean) return Integer;
11+
912
private
1013
type T is tagged record
1114
X : Integer;

testsuite/tests/instr-cov/expr_func/completion/test.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
gnatcov used to instrument such expression function, which resulted in
77
introducing a new primitive (the wrapper generated for MC/DC instrumentation),
88
which was not defined for derived types.
9+
10+
This also checks that such expression functions *are* instrumented when they
11+
are not in a package spec: primitives can be declared only in package specs.
912
"""
1013

1114
from SCOV.minicheck import build_run_and_coverage, check_xcov_reports
@@ -32,7 +35,8 @@
3235
"xcov",
3336
{
3437
"main.adb.xcov": {"+": {5, 7}},
35-
"pak.ads.xcov": {"+": {5, 10, 11, 12, 17, 18, 19}, "?": {15, 22}},
38+
"pak.ads.xcov": {"+": {5, 13, 14, 15, 20, 21, 22}, "?": {18, 25}},
39+
"pak.adb.xcov": {"+": {5, 6, 7, 12, 13, 14}, "-": {10, 17, 20, 23}},
3640
},
3741
)
3842

tools/gnatcov/instrument-ada_unit.adb

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,10 @@ package body Instrument.Ada_Unit is
456456
function Unwrap (N : Expr) return Expr;
457457
-- Strip Paren_Expr from N
458458

459+
function In_Package_Spec (N : Ada_Node'Class) return Boolean;
460+
-- Return whether N is a direct child of a package specification's
461+
-- declarative part (the public or the private one).
462+
459463
function Inclusive_End_Sloc
460464
(SL : Source_Location_Range) return Source_Location;
461465
-- End slocs from Libadalang nodes are exclusive: the correspond to the
@@ -4343,7 +4347,13 @@ package body Instrument.Ada_Unit is
43434347
end if;
43444348

43454349
if Is_Expr_Function then
4346-
if Return_Type_Is_Controlling (UIC, Common_Nodes) then
4350+
4351+
-- If N does not appear in a package spec, creating the augmented
4352+
-- expression function for it will not create a new primitive.
4353+
4354+
if Return_Type_Is_Controlling (UIC, Common_Nodes)
4355+
and then In_Package_Spec (N)
4356+
then
43474357

43484358
-- For the moment when an expression function is a primitive of
43494359
-- a tagged type T, and that T is the return type of the EF,
@@ -7654,6 +7664,28 @@ package body Instrument.Ada_Unit is
76547664
return Unwrapped_N;
76557665
end Unwrap;
76567666

7667+
---------------------
7668+
-- In_Package_Spec --
7669+
---------------------
7670+
7671+
function In_Package_Spec (N : Ada_Node'Class) return Boolean is
7672+
Decl_Part : Declarative_Part;
7673+
begin
7674+
if N.Is_Null
7675+
or else N.Parent.Is_Null
7676+
or else N.Parent.Kind /= Ada_Ada_Node_List
7677+
or else N.Parent.Parent.Is_Null
7678+
or else N.Parent.Parent.Kind not in Ada_Declarative_Part_Range
7679+
then
7680+
return False;
7681+
end if;
7682+
7683+
Decl_Part := N.Parent.Parent.As_Declarative_Part;
7684+
return
7685+
not Decl_Part.Parent.Is_Null
7686+
and then Decl_Part.Parent.Kind = Ada_Package_Decl;
7687+
end In_Package_Spec;
7688+
76577689
------------------------
76587690
-- Inclusive_End_Sloc --
76597691
------------------------

0 commit comments

Comments
 (0)