Skip to content

Commit 8538ec5

Browse files
committed
Merge branch 'mr/thevenoux-langkit-query-language#541' into 'master'
Improve Silent_Exception_Handlers to support access-to-subprograms Closes #541 See merge request eng/libadalang/langkit-query-language!533
2 parents 7841541 + 22ef936 commit 8538ec5

File tree

5 files changed

+87
-2
lines changed

5 files changed

+87
-2
lines changed

lkql_checker/share/lkql/silent_exception_handlers.lkql

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
import stdlib
22
import control_flow
33

4+
5+
fun qualified_name(name) = {
6+
|" Return the fully qualified name of ``name``. This function handles
7+
|" access-to-subprogram calls.
8+
val name = match name
9+
| ce@CallExpr => ce.f_name
10+
| ed@ExplicitDeref => ed.f_prefix
11+
| * => name;
12+
13+
name.p_referenced_defining_name().p_canonical_fully_qualified_name()
14+
}
15+
416
@check(message="silent exception handler",
517
category="Style", subcategory="Programming Practice",
618
auto_fix=(n, ctx) => ctx.add_last(n.f_stmts, new RaiseStmt(null, null)))
@@ -72,9 +84,9 @@ fun silent_exception_handlers(node, subprograms=[], subprogram_regexps=[]) =
7284
{
7385
fun is_raise_or_log(stmt) =
7486
stmt is (RaiseStmt
75-
| n@BaseId(p_is_call(): true)
87+
| n@Name(p_is_call(): true)
7688
when n.p_referenced_decl() is decl@BasicDecl
77-
when match decl.p_canonical_fully_qualified_name()
89+
when match qualified_name(n)
7890
| "^ada.exceptions.(raise_exception|reraise_occurrence)$" => true
7991
| n => [s for s in subprograms if n == s] or
8092
[r for r in subprogram_regexps
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
procedure Main is
2+
-- Implicit deref case
3+
4+
type Proc_Access is access procedure (I : Integer);
5+
6+
procedure Test (A, B : Proc_Access) is
7+
begin
8+
-- Implicit deref cases
9+
begin
10+
null;
11+
exception
12+
when Program_Error => A (1); -- FLAG
13+
when others => B (1); -- NO FLAG
14+
end;
15+
16+
-- Explicit deref cases
17+
begin
18+
null;
19+
exception
20+
when Program_Error => A.all (1); -- FLAG
21+
when others => B.all (1); -- NO FLAG
22+
end;
23+
end Test;
24+
25+
package P is
26+
type T is tagged null record;
27+
28+
procedure P (A : T);
29+
30+
type T_Access is access function return T;
31+
end P;
32+
33+
package body P is
34+
procedure P (A : T) is null;
35+
36+
procedure Test (X, Y : T_Access) is
37+
begin
38+
-- Explicit deref in dotted call cases
39+
begin
40+
null;
41+
exception
42+
when Program_Error => X.all.P; -- FLAG
43+
when others => Y.all.P; -- NO FLAG
44+
end;
45+
end Test;
46+
end P;
47+
48+
begin
49+
null;
50+
end Main;
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: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
main.adb:12:10: rule violation: silent exception handler
2+
12 | when Program_Error => A (1); -- FLAG
3+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4+
5+
main.adb:20:10: rule violation: silent exception handler
6+
20 | when Program_Error => A.all (1); -- FLAG
7+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8+
9+
main.adb:42:13: rule violation: silent exception handler
10+
42 | when Program_Error => X.all.P; -- FLAG
11+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
12+
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
driver: 'checker'
2+
description: |
3+
Check that the Silent_Exception_Handles rule handles calls resulting of an
4+
access dereference.
5+
rule_name: silent_exception_handlers
6+
project: prj.gpr
7+
rule_arguments:
8+
silent_exception_handlers.subprograms: '["main.test.b"]'
9+
silent_exception_handlers.subprogram_regexps: '["\.[Y]$"]'

0 commit comments

Comments
 (0)