Skip to content

Commit 65d0412

Browse files
authored
Merge pull request #1194 from geoffw0/dead-goto
CPP: Fix false positive from DeadCodeGoto.ql
2 parents eae2fe5 + 2e10687 commit 65d0412

File tree

4 files changed

+43
-0
lines changed

4 files changed

+43
-0
lines changed

change-notes/1.21/analysis-cpp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
| **Query** | **Expected impact** | **Change** |
1313
|----------------------------|------------------------|------------------------------------------------------------------|
14+
| Dead code due to goto or break statement (`cpp/dead-code-goto`) | Fewer false positive results | Functions containing preprocessor logic are now excluded from this analysis. |
1415
| Mismatching new/free or malloc/delete (`cpp/new-free-mismatch`) | Fewer false positive results | Fixed an issue where functions were being identified as allocation functions inappropriately. Also affects `cpp/new-array-delete-mismatch` and `cpp/new-delete-array-mismatch`. |
1516
| Overflow in uncontrolled allocation size (`cpp/uncontrolled-allocation-size`) | More correct results | This query has been reworked so that it can find a wider variety of results. |
1617
| Memory may not be freed (`cpp/memory-may-not-be-freed`) | More correct results | Support added for more Microsoft-specific allocation functions, including `LocalAlloc`, `GlobalAlloc`, `HeapAlloc` and `CoTaskMemAlloc`. |

cpp/ql/src/Critical/DeadCodeGoto.ql

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*/
1111

1212
import cpp
13+
import semmle.code.cpp.commons.Exclusions
1314

1415
Stmt getNextRealStmt(Block b, int i) {
1516
result = b.getStmt(i + 1) and
@@ -30,4 +31,6 @@ where b.getStmt(i) = js
3031
// the next statement isn't a loop that can be jumped into
3132
and not exists (LabelStmt ls | s.(Loop).getStmt().getAChild*() = ls)
3233
and not exists (SwitchCase sc | s.(Loop).getStmt().getAChild*() = sc)
34+
// no preprocessor logic applies
35+
and not functionContainsPreprocCode(js.getEnclosingFunction())
3336
select js, "This statement makes $@ unreachable.", s, s.toString()

cpp/ql/src/semmle/code/cpp/commons/Exclusions.qll

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,3 +58,16 @@ predicate functionContainsDisabledCode(Function f) {
5858
)
5959
)
6060
}
61+
62+
/**
63+
* Holds if the function `f` contains code that could be excluded by the preprocessor.
64+
*/
65+
predicate functionContainsPreprocCode(Function f) {
66+
// `f` contains a preprocessor branch
67+
exists(PreprocessorBranchDirective pbd, string file, int pbdStartLine, int fBlockStartLine, int fBlockEndLine |
68+
functionLocation(f, file, fBlockStartLine, fBlockEndLine) and
69+
pbdLocation(pbd, file, pbdStartLine) and
70+
pbdStartLine <= fBlockEndLine and
71+
pbdStartLine >= fBlockStartLine
72+
)
73+
}

cpp/ql/test/query-tests/Critical/DeadCodeGoto/test.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,3 +81,29 @@ void test7(int x, int cond) {
8181
}
8282
end:
8383
}
84+
85+
#define CONFIG_DEFINE
86+
87+
void test8() {
88+
int x = 0;
89+
90+
#ifdef CONFIG_DEFINE
91+
goto skip; // GOOD (the `x++` is still reachable in some configurations)
92+
#endif
93+
x++;
94+
95+
skip:
96+
}
97+
98+
void test9() {
99+
int x = 0;
100+
101+
#ifdef CONFIG_NOTDEFINED
102+
goto mid;
103+
#endif
104+
goto end; // GOOD (the `x++` is still reachable in some configurations)
105+
mid:
106+
x++;
107+
108+
end:
109+
}

0 commit comments

Comments
 (0)