Skip to content

Commit 6ed0ebb

Browse files
committed
DeadCode: Add MISRA C 2012 Rule 2.2
Add support for Rule 2.2 by adoptiing the DeadCode shared query. A small modification has been made to ensure results which include macro expansions are reported, unless the macro fully generates the statement.
1 parent 3b31915 commit 6ed0ebb

File tree

9 files changed

+131
-16
lines changed

9 files changed

+131
-16
lines changed
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
| test.c:20:3:20:27 | declaration | This statement is dead code. |
2+
| test.c:21:3:21:12 | ExprStmt | This statement is dead code. |
3+
| test.c:22:3:22:12 | ExprStmt | This statement is dead code. |
4+
| test.c:24:3:26:3 | if (...) ... | This statement is dead code. |
5+
| test.c:36:3:37:3 | if (...) ... | This statement is dead code. |
6+
| test.c:39:3:39:4 | { ... } | This statement is dead code. |
7+
| test.c:40:3:42:3 | { ... } | This statement is dead code. |
8+
| test.c:56:6:57:3 | { ... } | This statement is dead code. |
9+
| test.c:67:46:68:3 | { ... } | This statement is dead code. |
10+
| test.c:71:3:71:8 | ExprStmt | This statement is dead code. |
11+
| test.c:73:3:73:21 | ExprStmt | This statement is dead code. |
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
// GENERATED FILE - DO NOT MODIFY
2+
import codingstandards.cpp.rules.deadcode.DeadCode

c/common/test/rules/deadcode/test.c

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C++ TEST CASE AND CHANGES
2+
// SHOULD BE REFLECTED THERE AS WELL.
3+
// Define true/false for compatibility with C++ test cases
4+
#define false 0
5+
#define true 1
6+
7+
int may_have_side_effects();
8+
int no_side_effects(int x) { return 1 + 2; }
9+
int no_side_effects_nondeterministic();
10+
11+
int test_dead_code(int x) {
12+
int live1 = may_have_side_effects(),
13+
live2 = may_have_side_effects(); // COMPLIANT
14+
int live3 = 0,
15+
live4 = may_have_side_effects(); // COMPLIANT
16+
int live5 = 0, live6 = 0; // COMPLIANT
17+
live5 = 1; // COMPLIANT
18+
live6 = 2; // COMPLIANT
19+
20+
int dead1 = 0, dead2 = 0; // NON_COMPLIANT
21+
dead1 = 1; // NON_COMPLIANT - useless assignment
22+
dead2 = 1; // NON_COMPLIANT - useless assignment
23+
24+
if (false) { // NON_COMPLIANT
25+
dead2 = 10; // Only used in dead or unreachable code
26+
}
27+
28+
if (true) { // COMPLIANT
29+
may_have_side_effects();
30+
}
31+
32+
if (may_have_side_effects()) { // COMPLIANT
33+
may_have_side_effects();
34+
}
35+
36+
if (true) { // NON_COMPLIANT
37+
}
38+
39+
{} // NON_COMPLIANT
40+
{ // NON_COMPLIANT
41+
1 + 2;
42+
}
43+
44+
{ // COMPLIANT
45+
may_have_side_effects();
46+
}
47+
48+
do { // COMPLIANT
49+
may_have_side_effects();
50+
} while (may_have_side_effects());
51+
52+
do { // COMPLIANT
53+
may_have_side_effects();
54+
} while (may_have_side_effects());
55+
56+
do { // NON_COMPLIANT
57+
} while (no_side_effects_nondeterministic());
58+
59+
while (may_have_side_effects()) { // COMPLIANT
60+
may_have_side_effects();
61+
}
62+
63+
while (may_have_side_effects()) { // COMPLIANT
64+
may_have_side_effects();
65+
}
66+
67+
while (no_side_effects_nondeterministic()) { // NON_COMPLIANT
68+
}
69+
70+
may_have_side_effects(); // COMPLIANT
71+
1 + 2; // NON_COMPLIANT
72+
73+
no_side_effects(x); // NON_COMPLIANT
74+
75+
return live5 + live6; // COMPLIANT
76+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/**
2+
* @id c/misra/dead-code
3+
* @name RULE-2-2: There shall be no dead code
4+
* @description Dead code complicates the program and can indicate a possible mistake on the part of
5+
* the programmer.
6+
* @kind problem
7+
* @precision very-high
8+
* @problem.severity warning
9+
* @tags external/misra/id/rule-2-2
10+
* readability
11+
* maintainability
12+
* external/misra/obligation/required
13+
*/
14+
15+
import cpp
16+
import codingstandards.c.misra
17+
import codingstandards.cpp.rules.deadcode.DeadCode
18+
19+
class MisraCDeadCodeQuery extends DeadCodeSharedQuery {
20+
MisraCDeadCodeQuery() { this = DeadCodePackage::deadCodeQuery() }
21+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
c/common/test/rules/deadcode/DeadCode.ql
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- `M0-1-9`: This query previously excluded all results which were affected by a macro expansion. This is because a macro may be expanded multiple times with code that is dead in one expansion but live in another. This query has been modified to exclude results only where the entirety of a statement is generated by a macro. This reduces false negatives where the statements liveness is not affected by the macro expansion.

cpp/common/src/codingstandards/cpp/rules/deadcode/DeadCode.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,8 +115,8 @@ query predicate problems(Stmt s, string message) {
115115
// MISRA defines dead code as an "_executed_ statement whose removal would not affect the program
116116
// output". We therefore exclude unreachable statements as they are, by definition, not executed.
117117
not s.getBasicBlock() = any(UnreachableBasicBlock ubb).getABasicBlock() and
118-
// Exclude code generated by macros, because the code may be "live" in other instantiations
119-
not s.isAffectedByMacro() and
118+
// Exclude code fully generated by macros, because the code may be "live" in other expansions
119+
not s.isInMacroExpansion() and
120120
// Exclude compiler generated statements
121121
not s.isCompilerGenerated()
122122
}
Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
| test.cpp:14:3:14:27 | declaration | This statement is dead code. |
2-
| test.cpp:15:3:15:12 | ExprStmt | This statement is dead code. |
3-
| test.cpp:16:3:16:12 | ExprStmt | This statement is dead code. |
4-
| test.cpp:18:3:20:3 | if (...) ... | This statement is dead code. |
5-
| test.cpp:30:3:31:3 | if (...) ... | This statement is dead code. |
6-
| test.cpp:33:3:33:4 | { ... } | This statement is dead code. |
7-
| test.cpp:34:3:36:3 | { ... } | This statement is dead code. |
8-
| test.cpp:50:6:51:3 | { ... } | This statement is dead code. |
9-
| test.cpp:61:46:62:3 | { ... } | This statement is dead code. |
10-
| test.cpp:65:3:65:8 | ExprStmt | This statement is dead code. |
11-
| test.cpp:67:3:67:21 | ExprStmt | This statement is dead code. |
12-
| test.cpp:69:3:70:3 | try { ... } | This statement is dead code. |
13-
| test.cpp:70:17:71:3 | { ... } | This statement is dead code. |
14-
| test.cpp:76:17:77:3 | { ... } | This statement is dead code. |
1+
| test.cpp:17:3:17:27 | declaration | This statement is dead code. |
2+
| test.cpp:18:3:18:12 | ExprStmt | This statement is dead code. |
3+
| test.cpp:19:3:19:12 | ExprStmt | This statement is dead code. |
4+
| test.cpp:21:3:23:3 | if (...) ... | This statement is dead code. |
5+
| test.cpp:33:3:34:3 | if (...) ... | This statement is dead code. |
6+
| test.cpp:36:3:36:4 | { ... } | This statement is dead code. |
7+
| test.cpp:37:3:39:3 | { ... } | This statement is dead code. |
8+
| test.cpp:53:6:54:3 | { ... } | This statement is dead code. |
9+
| test.cpp:64:46:65:3 | { ... } | This statement is dead code. |
10+
| test.cpp:68:3:68:8 | ExprStmt | This statement is dead code. |
11+
| test.cpp:70:3:70:21 | ExprStmt | This statement is dead code. |
12+
| test.cpp:72:3:73:3 | try { ... } | This statement is dead code. |
13+
| test.cpp:73:17:74:3 | { ... } | This statement is dead code. |
14+
| test.cpp:79:17:80:3 | { ... } | This statement is dead code. |

cpp/common/test/rules/deadcode/test.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
// NOTICE: THE TEST CASES BELOW ARE ALSO INCLUDED IN THE C TEST CASE AND CHANGES
2+
// SHOULD BE REFLECTED THERE AS WELL.
3+
14
int may_have_side_effects();
25
int no_side_effects(int x) { return 1 + 2; }
36
int no_side_effects_nondeterministic();

0 commit comments

Comments
 (0)