Skip to content

Commit 07bcc99

Browse files
committed
Merge branch 'topic/133' into 'master'
Rule 'unassigned_out_parameters': also check the subp's decl part. Closes #133 See merge request eng/libadalang/langkit-query-language!220
2 parents d849b42 + 6593cb5 commit 07bcc99

File tree

7 files changed

+70
-30
lines changed

7 files changed

+70
-30
lines changed

lkql_checker/doc/gnatcheck_rm/predefined_rules.rst

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8321,17 +8321,17 @@ This rule has the following (mandatory) parameter for the ``+R`` option:
83218321

83228322
.. index:: Unassigned_OUT_Parameters
83238323

8324-
Flag procedures' ``out`` parameters that are not assigned.
8324+
Flag subprograms' ``out`` parameters that are not assigned.
83258325

8326-
An ``out`` parameter is flagged if the *sequence of statements* of
8327-
the procedure body (before the procedure body's exception part, if any)
8328-
contains no assignment to the parameter.
8326+
An ``out`` parameter is flagged if neither the *declarative part* nor the
8327+
*sequence of statements* of the subprogram body (before the subprogram body's
8328+
exception part, if any) contain an assignment to the parameter.
83298329

83308330
An ``out`` parameter is flagged if an *exception handler* contains neither an
83318331
assignment to the parameter nor a raise statement nor a call to a procedure
83328332
marked No_Return.
83338333

8334-
Bodies of generic procedures are also considered.
8334+
Bodies of generic subprograms are also considered.
83358335

83368336
The following are treated as assignments to an ``out`` parameter:
83378337

@@ -8345,6 +8345,10 @@ The rule has an optional parameter for the ``+R`` option:
83458345
Ignore assignments to subcomponents of an ``out`` parameter when detecting
83468346
if the parameter is assigned.
83478347

8348+
.. note:: An assignment to a subprogram's parameter can occur in the subprogram
8349+
body's *declarative part* in the presence of a nested subprogram declaration
8350+
which itself contains an assignment to the enclosing subprogram's parameter.
8351+
83488352
.. warning:: This rule only detects the described cases of unassigned variables
83498353
and doesn't provide a full guarantee that there is no uninitialized access.
83508354
It is only a partial replacement for the validity checks provided by

lkql_checker/share/lkql/unassigned_out_parameters.lkql

Lines changed: 19 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
# Flag procedures' out parameters that are not assigned.
2-
# An out parameter is flagged if the sequence of statements of the procedure
3-
# body (before the procedure body's exception part, if any) contains no
1+
# Flag subprogram' out parameters that are not assigned.
2+
# An out parameter is flagged if the sequence of statements of the subprogram
3+
# body (before the subprogram body's exception part, if any) contains no
44
# assignment to the parameter.
55
# An out parameter is also flagged if an exception handler contains neither an
66
# assignment to the parameter nor a raise statement nor a call to a procedure
77
# marked No_Return.
8-
# Bodies of generic procedures are also considered.
8+
# Bodies of generic subprograms are also considered.
99
#
1010
# The following are treated as assignments to an out parameter:
1111
# - an assignment statement, with the parameter or some component as the target
@@ -51,30 +51,24 @@ fun check_exception_handler(param, name, h, ignore_comp) =
5151
p_has_aspect("No_Return"))) or
5252
check_stmts(param, name, h, ignore_comp)
5353

54-
fun enclosing_body_stmts(node) =
55-
match stdlib.enclosing_body(node)
56-
| null => null
57-
| NullSubpDecl => null
58-
| p => p.f_stmts
59-
60-
@unit_check(help="OUT parameters do not get values in procedure bodies",
54+
@unit_check(help="OUT parameters do not get values in subprogram bodies",
6155
category="Feature")
6256
fun unassigned_out_parameters(unit, ignore_component_assignments=false) = [
6357
{message: "unassigned OUT parameter " & n.f_name.text, loc: n}
6458
for n in from unit.root
6559
# Look for out parameters of subprogram bodies only
6660
select node@DefiningName(parent: DefiningNameList(parent:
67-
ParamSpec(f_mode: ModeOut,
68-
parent: ParamSpecList(parent: Params(parent:
69-
SubpSpec(parent: SubpBody))))))
70-
when {
71-
val f = enclosing_body_stmts(node);
72-
val decl = node.p_basic_decl();
73-
74-
f and not (
75-
check_stmts(decl, node.f_name, f.f_stmts, ignore_component_assignments)
76-
and not [m for m in (from f.f_exceptions select h@ExceptionHandler
77-
when not check_exception_handler(decl, node.f_name, h,
78-
ignore_component_assignments))
79-
])
80-
}]
61+
decl@ParamSpec(f_mode: ModeOut,
62+
parent: ParamSpecList(parent: Params(parent:
63+
SubpSpec(parent: body@SubpBody))))))
64+
when not (
65+
check_stmts(decl, node.f_name, body.f_decls,
66+
ignore_component_assignments)
67+
or check_stmts(decl, node.f_name, body.f_stmts.f_stmts,
68+
ignore_component_assignments)
69+
) or stdlib.any([
70+
m for m in (from body.f_stmts.f_exceptions select h@ExceptionHandler
71+
when not check_exception_handler(decl, node.f_name, h,
72+
ignore_component_assignments))
73+
])
74+
]

testsuite/tests/checks/unassigned_out_params/params.adb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,17 @@ procedure Params is
8787
raise;
8888
end;
8989

90+
function Func_With_Out_Param (X : in out Integer) return Integer is
91+
begin
92+
X := 1;
93+
return 2;
94+
end Func_With_Out_Param;
95+
96+
procedure Proc_Param_Assigned_In_Decl_Part (X : in out Integer) is
97+
I : Integer := Func_With_Out_Param (X);
98+
begin
99+
null;
100+
end Proc_Param_Assigned_In_Decl_Part;
90101
begin
91102
null;
92103
end Params;
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
project Prj is
2+
end Prj;
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
procedure Test is
2+
procedure P
3+
(A : out Integer; -- NOFLAG
4+
B : out Integer -- NOFLAG
5+
)
6+
is
7+
procedure Init_A is
8+
begin
9+
A := 2;
10+
end Init_A;
11+
begin
12+
Init_A;
13+
14+
declare
15+
procedure Init_B is
16+
begin
17+
B := 2;
18+
end Init_B;
19+
begin
20+
Init_B;
21+
end;
22+
end P;
23+
begin
24+
null;
25+
end Test;

testsuite/tests/checks/unassigned_out_params_nested_subp/test.out

Whitespace-only changes.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
driver: 'checker'
2+
rule_name: 'Unassigned_OUT_Parameters'
3+
project: 'prj.gpr'
4+

0 commit comments

Comments
 (0)