-
Notifications
You must be signed in to change notification settings - Fork 66
Implement final MISRA C 2023 rule amendments #872
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 6 commits into
main
from
michaelrfairhurst/final-misra-c-rule-amendments
Mar 28, 2025
Merged
Changes from 4 commits
Commits
Show all changes
6 commits
Select commit
Hold shift + click to select a range
e30b3c3
Implement final MISRA 2023 rule amendments
MichaelRFairhurst a1142f3
reformat (and reformat generic with clang-format 11)
MichaelRFairhurst fd9fc0d
format IrreplaceableFunctionLikeMacro.qll
MichaelRFairhurst fbbb19d
Readd removed newline
MichaelRFairhurst 6b9dc41
Feedback
MichaelRFairhurst a03892c
Merge remote-tracking branch 'origin/main' into michaelrfairhurst/fin…
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
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
39 changes: 39 additions & 0 deletions
39
c/misra/src/rules/RULE-18-6/ThreadLocalObjectAddressCopiedToGlobalObject.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,39 @@ | ||
/** | ||
* @id c/misra/thread-local-object-address-copied-to-global-object | ||
* @name RULE-18-6: The address of an object with thread-local storage shall not be copied to a global object | ||
* @description Storing the address of a thread-local object in a global object will result in | ||
* undefined behavior if the address is accessed after the relevant thread is | ||
* terminated. | ||
* @kind problem | ||
* @precision very-high | ||
* @problem.severity error | ||
* @tags external/misra/id/rule-18-6 | ||
* correctness | ||
* external/misra/c/2012/amendment3 | ||
* external/misra/obligation/required | ||
*/ | ||
|
||
import cpp | ||
import codingstandards.c.misra | ||
import codingstandards.c.Objects | ||
import codingstandards.cpp.Concurrency | ||
|
||
from AssignExpr assignment, Element threadLocal, ObjectIdentity static | ||
where | ||
not isExcluded(assignment, Pointers1Package::threadLocalObjectAddressCopiedToGlobalObjectQuery()) and | ||
assignment.getLValue() = static.getASubobjectAccess() and | ||
static.getStorageDuration().isStatic() and | ||
( | ||
exists(ObjectIdentity threadLocalObj | | ||
threadLocal = threadLocalObj and | ||
assignment.getRValue() = threadLocalObj.getASubobjectAddressExpr() and | ||
threadLocalObj.getStorageDuration().isThread() | ||
) | ||
or | ||
exists(TSSGetFunctionCall getCall | | ||
threadLocal = getCall.getKey() and | ||
assignment.getRValue() = getCall | ||
) | ||
) | ||
select assignment, "Thread local object $@ address copied to static object $@.", | ||
threadLocal.getLocation(), threadLocal.toString(), static.getLocation(), static.toString() |
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
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
1 change: 0 additions & 1 deletion
1
c/misra/test/rules/RULE-1-4/EmergentLanguageFeaturesUsed.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
4 changes: 4 additions & 0 deletions
4
c/misra/test/rules/RULE-18-6/ThreadLocalObjectAddressCopiedToGlobalObject.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:29:3:29:10 | ... = ... | Thread local object $@ address copied to static object $@. | test.c:8:19:8:20 | test.c:8:19:8:20 | t1 | test.c:12:6:12:7 | test.c:12:6:12:7 | g2 | | ||
| test.c:55:3:55:14 | ... = ... | Thread local object $@ address copied to static object $@. | test.c:10:17:10:18 | test.c:10:17:10:18 | t3 | test.c:13:3:13:4 | test.c:13:3:13:4 | g3 | | ||
| test.c:152:3:152:21 | ... = ... | Thread local object $@ address copied to static object $@. | test.c:152:16:152:20 | test.c:152:16:152:20 | & ... | test.c:12:6:12:7 | test.c:12:6:12:7 | g2 | | ||
| test.c:155:3:155:23 | ... = ... | Thread local object $@ address copied to static object $@. | test.c:155:18:155:22 | test.c:155:18:155:22 | & ... | test.c:13:3:13:4 | test.c:13:3:13:4 | g3 | |
1 change: 1 addition & 0 deletions
1
c/misra/test/rules/RULE-18-6/ThreadLocalObjectAddressCopiedToGlobalObject.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-18-6/ThreadLocalObjectAddressCopiedToGlobalObject.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,169 @@ | ||
#include <threads.h> | ||
|
||
typedef struct { | ||
int *p; | ||
int m | ||
} s; | ||
|
||
_Thread_local int t1; | ||
_Thread_local int *t2; | ||
_Thread_local s t3; | ||
int g1; | ||
int *g2; | ||
s g3; | ||
|
||
void f1() { | ||
// Regular object accesses | ||
t1 = t1; // COMPLIANT | ||
t1 = *t2; // COMPLIANT | ||
t1 = g1; // COMPLIANT | ||
t1 = *g2; // COMPLIANT | ||
g1 = t1; // COMPLIANT | ||
g1 = *t2; // COMPLIANT | ||
g1 = g1; // COMPLIANT | ||
g1 = *g2; // COMPLIANT | ||
t2 = &t1; // COMPLIANT | ||
t2 = t2; // COMPLIANT | ||
t2 = &g1; // COMPLIANT | ||
t2 = g2; // COMPLIANT | ||
g2 = &t1; // NON-COMPLIANT | ||
g2 = t2; // COMPLIANT | ||
g2 = &g1; // COMPLIANT | ||
g2 = g2; // COMPLIANT | ||
*t2 = t1; // COMPLIANT | ||
*t2 = *t2; // COMPLIANT | ||
*t2 = g1; // COMPLIANT | ||
*t2 = *g2; // COMPLIANT | ||
*g2 = t1; // COMPLIANT | ||
*g2 = *t2; // COMPLIANT | ||
*g2 = g1; // COMPLIANT | ||
*g2 = *g2; // COMPLIANT | ||
|
||
// Subobject accesses | ||
t3.m = t3.m; // COMPLIANT | ||
t3.m = *t3.p; // COMPLIANT | ||
t3.m = g3.m; // COMPLIANT | ||
t3.m = *g3.p; // COMPLIANT | ||
g3.m = t3.m; // COMPLIANT | ||
g3.m = *t3.p; // COMPLIANT | ||
g3.m = g3.m; // COMPLIANT | ||
g3.m = *g3.p; // COMPLIANT | ||
t3.p = &t3.m; // COMPLIANT | ||
t3.p = t3.p; // COMPLIANT | ||
t3.p = &g3.m; // COMPLIANT | ||
t3.p = g3.p; // COMPLIANT | ||
g3.p = &t3.m; // NON-COMPLIANT | ||
g3.p = t3.p; // COMPLIANT | ||
g3.p = &g3.m; // COMPLIANT | ||
g3.p = g3.p; // COMPLIANT | ||
*t3.p = t3.m; // COMPLIANT | ||
*t3.p = *t3.p; // COMPLIANT | ||
*t3.p = g3.m; // COMPLIANT | ||
*t3.p = *g3.p; // COMPLIANT | ||
*g3.p = t3.m; // COMPLIANT | ||
*g3.p = *t3.p; // COMPLIANT | ||
*g3.p = g3.m; // COMPLIANT | ||
*g3.p = *g3.p; // COMPLIANT | ||
|
||
// Storing values in locals (automatic storage duration) | ||
int l1; | ||
int *l2; | ||
s l3; | ||
|
||
l1 = l1; // COMPLIANT | ||
l1 = *l2; // COMPLIANT | ||
l1 = l3.m; // COMPLIANT | ||
l1 = *l3.p; // COMPLIANT | ||
l1 = t1; // COMPLIANT | ||
l1 = *t2; // COMPLIANT | ||
l1 = t3.m; // COMPLIANT | ||
l1 = *t3.p; // COMPLIANT | ||
l1 = g1; // COMPLIANT | ||
l1 = *g2; // COMPLIANT | ||
l1 = g3.m; // COMPLIANT | ||
l1 = *g3.p; // COMPLIANT | ||
l2 = &l1; // COMPLIANT | ||
l2 = l2; // COMPLIANT | ||
l2 = &l3.m; // COMPLIANT | ||
l2 = l3.p; // COMPLIANT | ||
l2 = &t1; // COMPLIANT | ||
l2 = t2; // COMPLIANT | ||
l2 = &t3.m; // COMPLIANT | ||
l2 = t3.p; // COMPLIANT | ||
l2 = &g1; // COMPLIANT | ||
l2 = g2; // COMPLIANT | ||
l2 = &g3.m; // COMPLIANT | ||
l2 = g3.p; // COMPLIANT | ||
*l2 = l1; // COMPLIANT | ||
*l2 = *l2; // COMPLIANT | ||
*l2 = l3.m; // COMPLIANT | ||
*l2 = *l3.p; // COMPLIANT | ||
*l2 = t1; // COMPLIANT | ||
*l2 = *t2; // COMPLIANT | ||
*l2 = t3.m; // COMPLIANT | ||
*l2 = *t3.p; // COMPLIANT | ||
*l2 = g1; // COMPLIANT | ||
*l2 = *g2; // COMPLIANT | ||
*l2 = g3.m; // COMPLIANT | ||
*l2 = *g3.p; // COMPLIANT | ||
l3.m = l1; // COMPLIANT | ||
l3.m = *l2; // COMPLIANT | ||
l3.m = l3.m; // COMPLIANT | ||
l3.m = *l3.p; // COMPLIANT | ||
l3.m = t1; // COMPLIANT | ||
l3.m = *t2; // COMPLIANT | ||
l3.m = t3.m; // COMPLIANT | ||
l3.m = *t3.p; // COMPLIANT | ||
l3.m = g1; // COMPLIANT | ||
l3.m = *g2; // COMPLIANT | ||
l3.m = g3.m; // COMPLIANT | ||
l3.m = *g3.p; // COMPLIANT | ||
l3.p = &l1; // COMPLIANT | ||
l3.p = l2; // COMPLIANT | ||
l3.p = &l3.m; // COMPLIANT | ||
l3.p = l3.p; // COMPLIANT | ||
l3.p = &t1; // COMPLIANT | ||
l3.p = t2; // COMPLIANT | ||
l3.p = &t3.m; // COMPLIANT | ||
l3.p = t3.p; // COMPLIANT | ||
l3.p = &g1; // COMPLIANT | ||
l3.p = g2; // COMPLIANT | ||
l3.p = &g3.m; // COMPLIANT | ||
l3.p = g3.p; // COMPLIANT | ||
*l3.p = l1; // COMPLIANT | ||
*l3.p = *l2; // COMPLIANT | ||
*l3.p = l3.m; // COMPLIANT | ||
*l3.p = *l3.p; // COMPLIANT | ||
*l3.p = t1; // COMPLIANT | ||
*l3.p = *t2; // COMPLIANT | ||
*l3.p = t3.m; // COMPLIANT | ||
*l3.p = *t3.p; // COMPLIANT | ||
*l3.p = g1; // COMPLIANT | ||
*l3.p = *g2; // COMPLIANT | ||
*l3.p = g3.m; // COMPLIANT | ||
*l3.p = *g3.p; // COMPLIANT | ||
|
||
// Storing local values in globals is covered by the shared query. | ||
} | ||
|
||
tss_t tss1; | ||
void f2() { | ||
g1 = *(int *)tss_get(&tss1); // COMPLIANT | ||
g2 = tss_get(&tss1); // NON-COMPLIANT | ||
*g2 = *(int *)tss_get(&tss1); // COMPLIANT | ||
g3.m = *(int *)tss_get(&tss1); // COMPLIANT | ||
g3.p = tss_get(&tss1); // NON-COMPLIANT | ||
*g3.p = *(int *)tss_get(&tss1); // COMPLIANT | ||
g1 = ((s *)tss_get(&tss1))->m; // COMPLIANT | ||
g1 = *((s *)tss_get(&tss1))->p; // COMPLIANT | ||
g2 = &((s *)tss_get(&tss1))->m; // NON-COMPLIANT[false negative] | ||
g2 = *((s *)tss_get(&tss1))->p; // COMPLIANT | ||
*g2 = ((s *)tss_get(&tss1))->m; // COMPLIANT | ||
*g2 = *((s *)tss_get(&tss1))->p; // COMPLIANT | ||
g3.m = ((s *)tss_get(&tss1))->m; // COMPLIANT | ||
g3.m = *((s *)tss_get(&tss1))->p; // COMPLIANT | ||
g3.p = &((s *)tss_get(&tss1))->m; // NON-COMPLIANT[false negative] | ||
g3.p = *((s *)tss_get(&tss1))->p; // COMPLIANT | ||
*g3.p = ((s *)tss_get(&tss1))->m; // COMPLIANT | ||
*g3.p = *((s *)tss_get(&tss1))->p; // COMPLIANT | ||
} |
28 changes: 16 additions & 12 deletions
28
c/misra/test/rules/RULE-21-12/ExceptionHandlingFeaturesOfFenvhUsed.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 |
---|---|---|
@@ -1,12 +1,16 @@ | ||
| test.c:4:11:4:23 | call to feclearexcept | Call to banned function feclearexcept. | | ||
| test.c:4:25:4:34 | FE_INVALID | Call to banned macro FE_INVALID. | | ||
| test.c:6:3:6:17 | call to fegetexceptflag | Call to banned function fegetexceptflag. | | ||
| test.c:6:24:6:36 | FE_ALL_EXCEPT | Call to banned macro FE_ALL_EXCEPT. | | ||
| test.c:7:3:7:15 | call to feraiseexcept | Call to banned function feraiseexcept. | | ||
| test.c:7:17:7:28 | FE_DIVBYZERO | Call to banned macro FE_DIVBYZERO. | | ||
| test.c:8:3:8:15 | call to feraiseexcept | Call to banned function feraiseexcept. | | ||
| test.c:8:17:8:27 | FE_OVERFLOW | Call to banned macro FE_OVERFLOW. | | ||
| test.c:9:3:9:17 | call to fesetexceptflag | Call to banned function fesetexceptflag. | | ||
| test.c:9:24:9:36 | FE_ALL_EXCEPT | Call to banned macro FE_ALL_EXCEPT. | | ||
| test.c:10:3:10:14 | call to fetestexcept | Call to banned function fetestexcept. | | ||
| test.c:10:16:10:27 | FE_UNDERFLOW | Call to banned macro FE_UNDERFLOW. | | ||
| test.c:2:1:2:17 | #include <fenv.h> | Include of banned header 'fenv.h'. | | ||
| test.c:6:11:6:23 | call to feclearexcept | Call to banned function 'feclearexcept'. | | ||
| test.c:6:25:6:34 | FE_INVALID | Expansion of banned macro 'FE_INVALID'. | | ||
| test.c:8:3:8:17 | call to fegetexceptflag | Call to banned function 'fegetexceptflag'. | | ||
| test.c:8:24:8:36 | FE_ALL_EXCEPT | Expansion of banned macro 'FE_ALL_EXCEPT'. | | ||
| test.c:9:3:9:15 | call to feraiseexcept | Call to banned function 'feraiseexcept'. | | ||
| test.c:9:17:9:28 | FE_DIVBYZERO | Expansion of banned macro 'FE_DIVBYZERO'. | | ||
| test.c:10:3:10:15 | call to feraiseexcept | Call to banned function 'feraiseexcept'. | | ||
| test.c:10:17:10:27 | FE_OVERFLOW | Expansion of banned macro 'FE_OVERFLOW'. | | ||
| test.c:11:3:11:17 | call to fesetexceptflag | Call to banned function 'fesetexceptflag'. | | ||
| test.c:11:24:11:36 | FE_ALL_EXCEPT | Expansion of banned macro 'FE_ALL_EXCEPT'. | | ||
| test.c:12:3:12:14 | call to fetestexcept | Call to banned function 'fetestexcept'. | | ||
| test.c:12:16:12:27 | FE_UNDERFLOW | Expansion of banned macro 'FE_UNDERFLOW'. | | ||
| test.c:15:3:15:10 | call to fesetenv | Call to banned function 'fesetenv'. | | ||
| test.c:16:3:16:13 | call to feupdateenv | Call to banned function 'feupdateenv'. | | ||
| test.c:17:3:17:12 | call to fesetround | Call to banned function 'fesetround'. | |
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
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,8 @@ | ||
- `DIR-4-9` - `FunctionOverFunctionLikeMacro.ql`: | ||
- Macros with `_Generic` now no longer reported. | ||
- `RULE-1-4` - `EmergentLanguageFeaturesUsed.ql`: | ||
- Ban on usage of `_Generics` removed. | ||
- `RULE-18-6` - `ThreadLocalObjectAddressCopiedToGlobalObject.ql`: | ||
- New query added to detect thread local objects assigned to static storage duration objects. | ||
- `RULE-21-12` - `ExceptionHandlingFeaturesOfFenvhUsed.ql`: | ||
- Added reports for `#include`ing "fenv.h", and for using `fesetenv`, `feupdatenv`, and `fesetround`. | ||
MichaelRFairhurst marked this conversation as resolved.
Show resolved
Hide resolved
|
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
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
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.