Skip to content

Commit 104bdc7

Browse files
Implement Misra-c Noreturn rule package.
Covers rules 17-9 through 17-11, regarding the use of the _Noreturn attribute.
1 parent 9e73400 commit 104bdc7

15 files changed

+349
-0
lines changed
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/**
2+
* @id c/misra/non-void-return-type-of-noreturn-function
3+
* @name RULE-17-10: A function declared with _noreturn shall have a return type of void
4+
* @description Function declared with _noreturn will by definition not return a value, and should
5+
* be declared to return void.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity recommendation
9+
* @tags external/misra/id/rule-17-10
10+
* external/misra/obligation/required
11+
*/
12+
13+
import cpp
14+
import codingstandards.c.misra
15+
16+
from Function f, Type returnType
17+
where
18+
not isExcluded(f, NoReturnPackage::nonVoidReturnTypeOfNoreturnFunctionQuery()) and
19+
f.getASpecifier().getName() = "noreturn" and
20+
returnType = f.getType() and
21+
not returnType instanceof VoidType
22+
select
23+
f, "The function " + f.getName() + " is declared _noreturn but has a return type of " + returnType.toString() + "."
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @id c/misra/function-with-no-returning-branch-should-be-noreturn
3+
* @name RULE-17-11: A function without a branch that returns shall be declared with _Noreturn
4+
* @description Functions which cannot return should be declared with _Noreturn.
5+
* @kind problem
6+
* @precision high
7+
* @problem.severity recommendation
8+
* @tags external/misra/id/rule-17-11
9+
* external/misra/obligation/advisory
10+
*/
11+
12+
import cpp
13+
import codingstandards.c.misra
14+
15+
from Function f
16+
where
17+
not isExcluded(f, NoReturnPackage::returnStatementInNoreturnFunctionQuery()) and
18+
not f.getASpecifier().getName() = "noreturn" and
19+
not exists(ReturnStmt s |
20+
f = s.getEnclosingFunction() and
21+
s.getBasicBlock().isReachable()
22+
)
23+
select
24+
f, "The function " + f.getName() + " cannot return and should be declared attribute _Noreturn."
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/**
2+
* @id c/misra/return-statement-in-noreturn-function
3+
* @name RULE-17-9: Verify that a function declared with _Noreturn does not return
4+
* @description Returning inside a function declared with _Noreturn is undefined behavior.
5+
* @kind problem
6+
* @precision very-high
7+
* @problem.severity error
8+
* @tags external/misra/id/rule-17-9
9+
* external/misra/obligation/mandatory
10+
*/
11+
12+
import cpp
13+
import codingstandards.c.misra
14+
15+
from Function f
16+
where
17+
not isExcluded(f, NoReturnPackage::returnStatementInNoreturnFunctionQuery()) and
18+
f.getASpecifier().getName() = "noreturn" and
19+
exists(ReturnStmt s |
20+
f = s.getEnclosingFunction() and
21+
s.getBasicBlock().isReachable()
22+
)
23+
select
24+
f, "The function " + f.getName() + " declared with attribute _Noreturn returns a value."
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
No expected results have yet been specified
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-17-10/NonVoidReturnTypeOfNoreturnFunction.ql

c/misra/test/rules/RULE-17-10/test.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
#include "stdlib.h"
2+
3+
void f1(); // COMPLIANT
4+
int f2(); // COMPLIANT
5+
_Noreturn void f3(); // COMPLIANT
6+
_Noreturn int f4(); // NON-COMPLIANT
7+
8+
void f5() { // COMPLIANT
9+
}
10+
11+
int f6() { // COMPLIANT
12+
return 0;
13+
}
14+
15+
_Noreturn void f7() { // COMPLIANT
16+
abort();
17+
}
18+
19+
_Noreturn int f8() { // NON-COMPLIANT
20+
abort();
21+
return 0;
22+
}
23+
24+
_Noreturn void* f9(); // NON-COMPLIANT
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
| test.c:7:6:7:21 | test_noreturn_f2 | The function test_noreturn_f2 cannot return and should be declared attribute _Noreturn. |
2+
| test.c:19:6:19:21 | test_noreturn_f4 | The function test_noreturn_f4 cannot return and should be declared attribute _Noreturn. |
3+
| test.c:48:6:48:21 | test_noreturn_f8 | The function test_noreturn_f8 cannot return and should be declared attribute _Noreturn. |
4+
| test.c:64:6:64:22 | test_noreturn_f10 | The function test_noreturn_f10 cannot return and should be declared attribute _Noreturn. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
rules/RULE-17-11/FunctionWithNoReturningBranchShouldBeNoreturn.ql

c/misra/test/rules/RULE-17-11/test.c

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
#include "stdlib.h"
2+
3+
_Noreturn void test_noreturn_f1(int i) { // COMPLIANT
4+
abort();
5+
}
6+
7+
void test_noreturn_f2(int i) { // NON_COMPLIANT
8+
abort();
9+
}
10+
11+
12+
_Noreturn void test_noreturn_f3(int i) { // COMPLIANT
13+
if (i > 0) {
14+
abort();
15+
}
16+
exit(1);
17+
}
18+
19+
void test_noreturn_f4(int i) { // NON_COMPLIANT
20+
if (i > 0) {
21+
abort();
22+
}
23+
exit(1);
24+
}
25+
26+
void test_noreturn_f5(int i) { // COMPLIANT
27+
if (i > 0) {
28+
return;
29+
}
30+
exit(1);
31+
}
32+
33+
void test_noreturn_f6(int i) { // COMPLIANT
34+
if (i > 0) {
35+
abort();
36+
}
37+
if (i < 0) {
38+
abort();
39+
}
40+
}
41+
42+
void test_noreturn_f7(int i) { // COMPLIANT
43+
if (i > 0) {
44+
abort();
45+
}
46+
}
47+
48+
void test_noreturn_f8(int i) { // NON_COMPLIANT
49+
if (i > 0) {
50+
abort();
51+
} else {
52+
abort();
53+
}
54+
}
55+
56+
_Noreturn void test_noreturn_f9(int i) { // COMPLIANT
57+
if (i > 0) {
58+
abort();
59+
} else {
60+
abort();
61+
}
62+
}
63+
64+
void test_noreturn_f10(int i) { // NON_COMPLIANT
65+
if (i > 0) {
66+
abort();
67+
}
68+
while (1) {
69+
i = 5;
70+
}
71+
}
72+
73+
_Noreturn void test_noreturn_f11(int i) { // COMPLIANT
74+
if (i > 0) {
75+
abort();
76+
}
77+
while (1) {
78+
i = 5;
79+
}
80+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
| test.c:7:16:7:31 | test_noreturn_f2 | The function test_noreturn_f2 declared with attribute _Noreturn returns a value. |
2+
| test.c:32:16:32:31 | test_noreturn_f5 | The function test_noreturn_f5 declared with attribute _Noreturn returns a value. |

0 commit comments

Comments
 (0)