-
Notifications
You must be signed in to change notification settings - Fork 66
Implement Misra-c Noreturn rule package. #713
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
lcartey
merged 10 commits into
main
from
michaelrfairhurst/implement-misra-c-noreturn-rule-package
Oct 4, 2024
Merged
Changes from all commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
104bdc7
Implement Misra-c Noreturn rule package.
MichaelRFairhurst 778db73
Fix false positives by supporting __attribute__((noreturn)), format.
MichaelRFairhurst c8e5091
Address feedback
MichaelRFairhurst 8991e5f
Fix format
MichaelRFairhurst b297513
Fix tests
MichaelRFairhurst 6f860fc
Add changelog; tweaks based on MRVA results.
MichaelRFairhurst 3356b5e
Fix format
MichaelRFairhurst 8ffbb1e
Update test expected message
MichaelRFairhurst 81fb797
Set FunctionWithNoReturningBranch... to very-high precision
MichaelRFairhurst 71b4c25
Fix NoReturn.json package description precision 17-11
MichaelRFairhurst File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
3 changes: 3 additions & 0 deletions
3
...test/rules/functionnoreturnattributecondition/FunctionNoReturnAttributeCondition.expected
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
| test.c:9:16:9:31 | test_noreturn_f2 | The function test_noreturn_f2 declared with attribute _Noreturn returns a value. | | ||
| test.c:34:16:34:31 | test_noreturn_f5 | The function test_noreturn_f5 declared with attribute _Noreturn returns a value. | | ||
| test.c:49:32:49:47 | test_noreturn_f7 | The function test_noreturn_f7 declared with attribute _Noreturn returns a value. | |
4 changes: 4 additions & 0 deletions
4
c/common/test/rules/functionnoreturnattributecondition/FunctionNoReturnAttributeCondition.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
// GENERATED FILE - DO NOT MODIFY | ||
import codingstandards.cpp.rules.functionnoreturnattributecondition.FunctionNoReturnAttributeCondition | ||
|
||
class TestFileQuery extends FunctionNoReturnAttributeConditionSharedQuery, TestQuery { } |
88 changes: 88 additions & 0 deletions
88
c/common/test/rules/functionnoreturnattributecondition/test.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
#include "setjmp.h" | ||
#include "stdlib.h" | ||
#include "threads.h" | ||
|
||
_Noreturn void test_noreturn_f1(int i) { // COMPLIANT | ||
abort(); | ||
} | ||
|
||
_Noreturn void test_noreturn_f2(int i) { // NON_COMPLIANT | ||
if (i > 0) { | ||
abort(); | ||
} | ||
if (i < 0) { | ||
abort(); | ||
} | ||
} | ||
|
||
_Noreturn void test_noreturn_f3(int i) { // COMPLIANT | ||
if (i > 0) { | ||
abort(); | ||
} | ||
exit(1); | ||
} | ||
|
||
void test_noreturn_f4(int i) { // COMPLIANT | ||
if (i > 0) { | ||
abort(); | ||
} | ||
if (i < 0) { | ||
abort(); | ||
} | ||
} | ||
|
||
_Noreturn void test_noreturn_f5(int i) { // NON_COMPLIANT | ||
if (i > 0) { | ||
abort(); | ||
} | ||
} | ||
|
||
_Noreturn void test_noreturn_f6(int i) { // COMPLIANT | ||
if (i > 0) { | ||
abort(); | ||
} | ||
while (1) { | ||
i = 5; | ||
} | ||
} | ||
|
||
__attribute__((noreturn)) void test_noreturn_f7(int i) { // NON_COMPLIANT | ||
if (i > 0) { | ||
abort(); | ||
} | ||
} | ||
|
||
__attribute__((noreturn)) void test_noreturn_f8(int i) { // COMPLIANT | ||
abort(); | ||
} | ||
|
||
_Noreturn void test_noreturn_f9(int i) { // COMPLIANT | ||
test_noreturn_f1(i); | ||
} | ||
|
||
_Noreturn void test_noreturn_f10(int i) { // COMPLIANT | ||
switch (i) { | ||
case 0: | ||
abort(); | ||
break; | ||
case 1: | ||
exit(0); | ||
break; | ||
case 2: | ||
_Exit(0); | ||
break; | ||
case 3: | ||
quick_exit(0); | ||
break; | ||
case 4: | ||
thrd_exit(0); | ||
break; | ||
default: | ||
jmp_buf jb; | ||
longjmp(jb, 0); | ||
} | ||
} | ||
|
||
_Noreturn void test_noreturn_f11(int i) { // COMPLIANT | ||
return test_noreturn_f11(i); | ||
} |
26 changes: 26 additions & 0 deletions
26
c/misra/src/rules/RULE-17-10/NonVoidReturnTypeOfNoreturnFunction.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/** | ||
* @id c/misra/non-void-return-type-of-noreturn-function | ||
* @name RULE-17-10: A function declared with _noreturn shall have a return type of void | ||
* @description Function declared with _noreturn will by definition not return a value, and should | ||
* be declared to return void. | ||
* @kind problem | ||
* @precision very-high | ||
* @problem.severity recommendation | ||
* @tags external/misra/id/rule-17-10 | ||
* correctness | ||
* external/misra/obligation/required | ||
*/ | ||
|
||
import cpp | ||
import codingstandards.c.misra | ||
import codingstandards.cpp.Noreturn | ||
|
||
from NoreturnFunction f, Type returnType | ||
where | ||
not isExcluded(f, NoReturnPackage::nonVoidReturnTypeOfNoreturnFunctionQuery()) and | ||
returnType = f.getType() and | ||
not returnType instanceof VoidType and | ||
not f.isCompilerGenerated() | ||
select f, | ||
"The function " + f.getName() + " is declared _noreturn but has a return type of " + | ||
returnType.toString() + "." |
28 changes: 28 additions & 0 deletions
28
c/misra/src/rules/RULE-17-11/FunctionWithNoReturningBranchShouldBeNoreturn.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/** | ||
* @id c/misra/function-with-no-returning-branch-should-be-noreturn | ||
* @name RULE-17-11: A function without a branch that returns shall be declared with _Noreturn | ||
* @description Functions which cannot return should be declared with _Noreturn. | ||
* @kind problem | ||
* @precision very-high | ||
* @problem.severity recommendation | ||
* @tags external/misra/id/rule-17-11 | ||
* correctness | ||
* external/misra/obligation/advisory | ||
*/ | ||
|
||
import cpp | ||
import codingstandards.c.misra | ||
import codingstandards.cpp.Noreturn | ||
|
||
from Function f | ||
where | ||
not isExcluded(f, NoReturnPackage::functionWithNoReturningBranchShouldBeNoreturnQuery()) and | ||
not f instanceof NoreturnFunction and | ||
not mayReturn(f) and | ||
f.hasDefinition() and | ||
not f.getName() = "main" and // Allowed exception; _Noreturn main() is undefined behavior. | ||
// Harden against c++ cases. | ||
not f.isFromUninstantiatedTemplate(_) and | ||
not f.isDeleted() and | ||
not f.isCompilerGenerated() | ||
select f, "The function " + f.getName() + " cannot return and should be declared as _Noreturn." |
21 changes: 21 additions & 0 deletions
21
c/misra/src/rules/RULE-17-9/ReturnStatementInNoreturnFunction.ql
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
/** | ||
* @id c/misra/return-statement-in-noreturn-function | ||
* @name RULE-17-9: Verify that a function declared with _Noreturn does not return | ||
* @description Returning inside a function declared with _Noreturn is undefined behavior. | ||
* @kind problem | ||
* @precision very-high | ||
* @problem.severity error | ||
* @tags external/misra/id/rule-17-9 | ||
* correctness | ||
* external/misra/obligation/mandatory | ||
*/ | ||
|
||
import cpp | ||
import codingstandards.c.misra | ||
import codingstandards.cpp.rules.functionnoreturnattributecondition.FunctionNoReturnAttributeCondition | ||
|
||
class ReturnStatementInNoreturnFunctionQuery extends FunctionNoReturnAttributeConditionSharedQuery { | ||
ReturnStatementInNoreturnFunctionQuery() { | ||
this = NoReturnPackage::returnStatementInNoreturnFunctionQuery() | ||
} | ||
} |
4 changes: 4 additions & 0 deletions
4
c/misra/test/rules/RULE-17-10/NonVoidReturnTypeOfNoreturnFunction.expected
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
| test.c:6:15:6:16 | f4 | The function f4 is declared _noreturn but has a return type of int. | | ||
| test.c:19:15:19:16 | f8 | The function f8 is declared _noreturn but has a return type of int. | | ||
| test.c:24:17:24:18 | f9 | The function f9 is declared _noreturn but has a return type of void *. | | ||
| test.c:26:31:26:33 | f10 | The function f10 is declared _noreturn but has a return type of int. | |
1 change: 1 addition & 0 deletions
1
c/misra/test/rules/RULE-17-10/NonVoidReturnTypeOfNoreturnFunction.qlref
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
rules/RULE-17-10/NonVoidReturnTypeOfNoreturnFunction.ql |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
#include "stdlib.h" | ||
|
||
void f1(); // COMPLIANT | ||
int f2(); // COMPLIANT | ||
_Noreturn void f3(); // COMPLIANT | ||
_Noreturn int f4(); // NON-COMPLIANT | ||
|
||
void f5() { // COMPLIANT | ||
} | ||
|
||
int f6() { // COMPLIANT | ||
return 0; | ||
} | ||
|
||
_Noreturn void f7() { // COMPLIANT | ||
abort(); | ||
} | ||
|
||
_Noreturn int f8() { // NON-COMPLIANT | ||
abort(); | ||
return 0; | ||
} | ||
|
||
_Noreturn void *f9(); // NON-COMPLIANT | ||
|
||
__attribute__((noreturn)) int f10(); // NON-COMPLIANT |
6 changes: 6 additions & 0 deletions
6
c/misra/test/rules/RULE-17-11/FunctionWithNoReturningBranchShouldBeNoreturn.expected
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
| test.c:7:6:7:21 | test_noreturn_f2 | The function test_noreturn_f2 cannot return and should be declared as _Noreturn. | | ||
| test.c:18:6:18:21 | test_noreturn_f4 | The function test_noreturn_f4 cannot return and should be declared as _Noreturn. | | ||
| test.c:47:6:47:21 | test_noreturn_f8 | The function test_noreturn_f8 cannot return and should be declared as _Noreturn. | | ||
| test.c:63:6:63:22 | test_noreturn_f10 | The function test_noreturn_f10 cannot return and should be declared as _Noreturn. | | ||
| test.c:97:6:97:22 | test_noreturn_f15 | The function test_noreturn_f15 cannot return and should be declared as _Noreturn. | | ||
| test.c:101:6:101:22 | test_noreturn_f16 | The function test_noreturn_f16 cannot return and should be declared as _Noreturn. | |
1 change: 1 addition & 0 deletions
1
c/misra/test/rules/RULE-17-11/FunctionWithNoReturningBranchShouldBeNoreturn.qlref
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
rules/RULE-17-11/FunctionWithNoReturningBranchShouldBeNoreturn.ql |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
#include "stdlib.h" | ||
|
||
_Noreturn void test_noreturn_f1(int i) { // COMPLIANT | ||
abort(); | ||
} | ||
|
||
void test_noreturn_f2(int i) { // NON_COMPLIANT | ||
abort(); | ||
} | ||
|
||
_Noreturn void test_noreturn_f3(int i) { // COMPLIANT | ||
if (i > 0) { | ||
abort(); | ||
} | ||
exit(1); | ||
} | ||
|
||
void test_noreturn_f4(int i) { // NON_COMPLIANT | ||
if (i > 0) { | ||
abort(); | ||
} | ||
exit(1); | ||
} | ||
|
||
void test_noreturn_f5(int i) { // COMPLIANT | ||
if (i > 0) { | ||
return; | ||
} | ||
exit(1); | ||
} | ||
|
||
void test_noreturn_f6(int i) { // COMPLIANT | ||
if (i > 0) { | ||
abort(); | ||
} | ||
if (i < 0) { | ||
abort(); | ||
} | ||
} | ||
|
||
void test_noreturn_f7(int i) { // COMPLIANT | ||
if (i > 0) { | ||
abort(); | ||
} | ||
} | ||
|
||
void test_noreturn_f8(int i) { // NON_COMPLIANT | ||
MichaelRFairhurst marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (i > 0) { | ||
abort(); | ||
} else { | ||
abort(); | ||
} | ||
} | ||
|
||
_Noreturn void test_noreturn_f9(int i) { // COMPLIANT | ||
if (i > 0) { | ||
abort(); | ||
} else { | ||
abort(); | ||
MichaelRFairhurst marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
|
||
void test_noreturn_f10(int i) { // NON_COMPLIANT | ||
if (i > 0) { | ||
abort(); | ||
} | ||
while (1) { | ||
i = 5; | ||
} | ||
} | ||
|
||
_Noreturn void test_noreturn_f11(int i) { // COMPLIANT | ||
if (i > 0) { | ||
abort(); | ||
} | ||
while (1) { | ||
i = 5; | ||
} | ||
} | ||
|
||
void test_noreturn_f12(); // COMPLIANT | ||
|
||
__attribute__((noreturn)) void test_noreturn_f13(int i) { // COMPLIANT | ||
abort(); | ||
} | ||
|
||
// Allowed by exception. It is undefined behavior for main() to be declared with | ||
// noreturn. | ||
int main(char **argv, int argc) { // COMPLIANT | ||
abort(); | ||
} | ||
|
||
_Noreturn void test_noreturn_f14(int i) { // COMPLIANT | ||
test_noreturn_f1(i); | ||
} | ||
|
||
void test_noreturn_f15(int i) { // NON_COMPLIANT | ||
test_noreturn_f1(i); | ||
} | ||
|
||
void test_noreturn_f16(int i) { // NON_COMPLIANT | ||
// Infinite tail recursion | ||
test_noreturn_f16(i); | ||
} |
1 change: 1 addition & 0 deletions
1
c/misra/test/rules/RULE-17-9/ReturnStatementInNoreturnFunction.testref
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
c/common/test/rules/functionnoreturnattributecondition/FunctionNoReturnAttributeCondition.ql |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
- `A7-6-1`, `MSC53-CPP`, `RULE-9-6-4` - `FunctionNoReturnAttbrituteCondition.qll` | ||
- Analysis expanded from functions with "noreturn" attribute, now includes the "noreturn" specifier as well to handle new c rules. No difference in C++ results expected. | ||
- Exclude compiler generated functions from being reported. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import cpp | ||
|
||
/** | ||
* A function marked with _Noreturn or __attribute((noreturn)) | ||
*/ | ||
class NoreturnFunction extends Function { | ||
NoreturnFunction() { | ||
this.getASpecifier().getName() = "noreturn" or | ||
this.getAnAttribute().getName() = "noreturn" | ||
} | ||
} | ||
|
||
/** | ||
* A function that may complete normally, and/or contains an explicit reachable | ||
* return statement. | ||
*/ | ||
predicate mayReturn(Function function) { | ||
exists(ReturnStmt s | | ||
function = s.getEnclosingFunction() and | ||
s.getBasicBlock().isReachable() | ||
) | ||
} |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.