Skip to content

Commit c8e5091

Browse files
Address feedback
1 parent 778db73 commit c8e5091

File tree

13 files changed

+86
-23
lines changed

13 files changed

+86
-23
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
| test.c:9:16:9:31 | test_noreturn_f2 | The function test_noreturn_f2 declared with attribute _Noreturn returns a value. |
2+
| test.c:34:16:34:31 | test_noreturn_f5 | The function test_noreturn_f5 declared with attribute _Noreturn returns a value. |
3+
| test.c:49:32:49:47 | test_noreturn_f7 | The function test_noreturn_f7 declared with attribute _Noreturn returns a value. |
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// GENERATED FILE - DO NOT MODIFY
2+
import codingstandards.cpp.rules.functionnoreturnattributecondition.FunctionNoReturnAttributeCondition
3+
4+
class TestFileQuery extends FunctionNoReturnAttributeConditionSharedQuery, TestQuery { }

c/misra/test/rules/RULE-17-9/test.c renamed to c/common/test/rules/functionnoreturnattributecondition/test.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
#include "stdlib.h"
2+
#include "threads.h"
3+
#include "setjmp.h"
24

35
_Noreturn void test_noreturn_f1(int i) { // COMPLIANT
46
abort();
@@ -52,4 +54,30 @@ __attribute__((noreturn)) void test_noreturn_f7(int i) { // NON_COMPLIANT
5254

5355
__attribute__((noreturn)) void test_noreturn_f8(int i) { // COMPLIANT
5456
abort();
57+
}
58+
59+
_Noreturn void test_noreturn_f9(int i) { // COMPLIANT
60+
test_noreturn_f1(i);
61+
}
62+
63+
_Noreturn void test_noreturn_f10(int i) { // COMPLIANT
64+
switch(i) {
65+
case 0:
66+
abort(); break;
67+
case 1:
68+
exit(0); break;
69+
case 2:
70+
_Exit(0); break;
71+
case 3:
72+
quick_exit(0); break;
73+
case 4:
74+
thrd_exit(0); break;
75+
default:
76+
jmp_buf jb;
77+
longjmp(jb, 0);
78+
}
79+
}
80+
81+
_Noreturn void test_noreturn_f11(int i) { // COMPLIANT
82+
return test_noreturn_f11(i);
5583
}

c/misra/src/rules/RULE-17-10/NonVoidReturnTypeOfNoreturnFunction.ql

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,18 +7,20 @@
77
* @precision very-high
88
* @problem.severity recommendation
99
* @tags external/misra/id/rule-17-10
10+
* correctness
1011
* external/misra/obligation/required
1112
*/
1213

1314
import cpp
1415
import codingstandards.c.misra
15-
import codingstandards.c.Noreturn
16+
import codingstandards.cpp.Noreturn
1617

1718
from NoreturnFunction f, Type returnType
1819
where
1920
not isExcluded(f, NoReturnPackage::nonVoidReturnTypeOfNoreturnFunctionQuery()) and
2021
returnType = f.getType() and
21-
not returnType instanceof VoidType
22+
not returnType instanceof VoidType and
23+
not f.isCompilerGenerated()
2224
select f,
2325
"The function " + f.getName() + " is declared _noreturn but has a return type of " +
2426
returnType.toString() + "."

c/misra/src/rules/RULE-17-11/FunctionWithNoReturningBranchShouldBeNoreturn.ql

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,21 @@
66
* @precision high
77
* @problem.severity recommendation
88
* @tags external/misra/id/rule-17-11
9+
* correctness
910
* external/misra/obligation/advisory
1011
*/
1112

1213
import cpp
1314
import codingstandards.c.misra
14-
import codingstandards.c.Noreturn
15+
import codingstandards.cpp.Noreturn
1516

1617
from Function f
1718
where
1819
not isExcluded(f, NoReturnPackage::returnStatementInNoreturnFunctionQuery()) and
1920
not f instanceof NoreturnFunction and
2021
not mayReturn(f) and
2122
f.hasDefinition() and
22-
f.getName() != "main" // Allowed exception; _Noreturn main() is undefined behavior.
23+
not f.getName() = "main" and // Allowed exception; _Noreturn main() is undefined behavior.
24+
not f.isCompilerGenerated()
2325
select f,
2426
"The function " + f.getName() + " cannot return and should be declared attribute _Noreturn."

c/misra/src/rules/RULE-17-9/ReturnStatementInNoreturnFunction.ql

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,16 @@
66
* @precision very-high
77
* @problem.severity error
88
* @tags external/misra/id/rule-17-9
9+
* correctness
910
* external/misra/obligation/mandatory
1011
*/
1112

1213
import cpp
1314
import codingstandards.c.misra
14-
import codingstandards.c.Noreturn
15+
import codingstandards.cpp.rules.functionnoreturnattributecondition.FunctionNoReturnAttributeCondition
1516

16-
from NoreturnFunction f
17-
where
18-
not isExcluded(f, NoReturnPackage::returnStatementInNoreturnFunctionQuery()) and
19-
mayReturn(f)
20-
select f, "The function " + f.getName() + " declared with attribute _Noreturn returns a value."
17+
class ReturnStatementInNoreturnFunctionQuery extends FunctionNoReturnAttributeConditionSharedQuery {
18+
ReturnStatementInNoreturnFunctionQuery() {
19+
this = NoReturnPackage::returnStatementInNoreturnFunctionQuery()
20+
}
21+
}

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,5 @@
22
| test.c:18:6:18:21 | test_noreturn_f4 | The function test_noreturn_f4 cannot return and should be declared attribute _Noreturn. |
33
| test.c:47:6:47:21 | test_noreturn_f8 | The function test_noreturn_f8 cannot return and should be declared attribute _Noreturn. |
44
| test.c:63:6:63:22 | test_noreturn_f10 | The function test_noreturn_f10 cannot return and should be declared attribute _Noreturn. |
5+
| test.c:97:6:97:22 | test_noreturn_f15 | The function test_noreturn_f15 cannot return and should be declared attribute _Noreturn. |
6+
| test.c:101:6:101:22 | test_noreturn_f16 | The function test_noreturn_f16 cannot return and should be declared attribute _Noreturn. |

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,4 +88,17 @@ __attribute__((noreturn)) void test_noreturn_f13(int i) { // COMPLIANT
8888
// noreturn.
8989
int main(char **argv, int argc) { // COMPLIANT
9090
abort();
91+
}
92+
93+
_Noreturn void test_noreturn_f14(int i) { // COMPLIANT
94+
test_noreturn_f1(i);
95+
}
96+
97+
void test_noreturn_f15(int i) { // NON_COMPLIANT
98+
test_noreturn_f1(i);
99+
}
100+
101+
void test_noreturn_f16(int i) { // NON_COMPLIANT
102+
// Infinite tail recursion
103+
test_noreturn_f16(i);
91104
}

c/misra/test/rules/RULE-17-9/ReturnStatementInNoreturnFunction.expected

Lines changed: 0 additions & 3 deletions
This file was deleted.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/functionnoreturnattributecondition/FunctionNoReturnAttributeCondition.ql

cpp/common/src/codingstandards/cpp/rules/functionnoreturnattributecondition/FunctionNoReturnAttributeCondition.qll

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,29 @@
55
import cpp
66
import codingstandards.cpp.Customizations
77
import codingstandards.cpp.Exclusions
8+
import codingstandards.cpp.Noreturn
89

910
abstract class FunctionNoReturnAttributeConditionSharedQuery extends Query { }
1011

1112
Query getQuery() { result instanceof FunctionNoReturnAttributeConditionSharedQuery }
1213

14+
/**
15+
* `noreturn` functions are declared differently in c/c++. Attempt to match
16+
* the description to the file; low risk if it chooses incorrectly.
17+
*/
18+
string describeNoreturn(Function f) {
19+
if f.getFile().getExtension() = ["c", "C", "h", "H"]
20+
then result = "_Noreturn"
21+
else result = "[[noreturn]]"
22+
}
23+
1324
/**
1425
* This checks that the return statement is reachable from the function entry point
1526
*/
16-
query predicate problems(Function f, string message) {
27+
query predicate problems(NoreturnFunction f, string message) {
1728
not isExcluded(f, getQuery()) and
18-
f.getAnAttribute().getName() = "noreturn" and
19-
exists(ReturnStmt s |
20-
f = s.getEnclosingFunction() and
21-
s.getBasicBlock().isReachable()
22-
) and
23-
message = "The function " + f.getName() + " declared with attribute [[noreturn]] returns a value."
29+
mayReturn(f) and
30+
not f.isCompilerGenerated() and
31+
message =
32+
"The function " + f.getName() + " declared with attribute " + describeNoreturn(f) + " returns a value."
2433
}

rule_packages/c/NoReturn.json

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"precision": "very-high",
1313
"severity": "recommendation",
1414
"short_name": "NonVoidReturnTypeOfNoreturnFunction",
15-
"tags": []
15+
"tags": ["correctness"]
1616
}
1717
],
1818
"title": "A function declared with _noreturn shall have a return type of void"
@@ -29,7 +29,7 @@
2929
"precision": "high",
3030
"severity": "recommendation",
3131
"short_name": "FunctionWithNoReturningBranchShouldBeNoreturn",
32-
"tags": []
32+
"tags": ["correctness"]
3333
}
3434
],
3535
"title": "A function without a branch that returns shall be declared with _Noreturn"
@@ -46,7 +46,8 @@
4646
"precision": "very-high",
4747
"severity": "error",
4848
"short_name": "ReturnStatementInNoreturnFunction",
49-
"tags": []
49+
"tags": ["correctness"],
50+
"shared_implementation_short_name": "FunctionNoReturnAttributeCondition"
5051
}
5152
],
5253
"title": "Verify that a function declared with _Noreturn does not return"

0 commit comments

Comments
 (0)