Skip to content

Commit 09d0548

Browse files
authored
Merge pull request #1237 from geoffw0/commentedoutcode2
CPP: Fix FPs from detecting commented out preprocessor logic
2 parents d8b47c8 + 2d15163 commit 09d0548

File tree

6 files changed

+132
-9
lines changed

6 files changed

+132
-9
lines changed

cpp/ql/src/Documentation/CommentedOutCode.qll

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,38 @@ private predicate looksLikeCode(string line) {
4747
)
4848
}
4949

50+
/**
51+
* Holds if there is a preprocessor directive on the line indicated by
52+
* `f` and `line` that we permit code comments besides. For example this
53+
* is considered acceptable:
54+
* ```
55+
* #ifdef MYMACRO
56+
* ...
57+
* #endif // #ifdef MYMACRO
58+
* ```
59+
*/
60+
private predicate preprocLine(File f, int line) {
61+
exists(PreprocessorDirective pd, Location l |
62+
(
63+
pd instanceof PreprocessorElse or
64+
pd instanceof PreprocessorElif or
65+
pd instanceof PreprocessorEndif
66+
) and
67+
pd.getLocation() = l and
68+
l.getFile() = f and
69+
l.getStartLine() = line
70+
)
71+
}
72+
5073
/**
5174
* The line of a C++-style comment within its file `f`.
5275
*/
5376
private int lineInFile(CppStyleComment c, File f) {
5477
f = c.getFile() and
55-
result = c.getLocation().getStartLine()
78+
result = c.getLocation().getStartLine() and
79+
80+
// Ignore comments on the same line as a preprocessor directive.
81+
not preprocLine(f, result)
5682
}
5783

5884
/**
@@ -89,9 +115,17 @@ private int commentId(CppStyleComment c, File f, int line) {
89115
*/
90116
class CommentBlock extends Comment {
91117
CommentBlock() {
92-
this instanceof CppStyleComment
93-
implies
94-
not exists(CppStyleComment pred, File f | lineInFile(pred, f) + 1 = lineInFile(this, f))
118+
(
119+
this instanceof CppStyleComment
120+
implies
121+
not exists(CppStyleComment pred, File f | lineInFile(pred, f) + 1 = lineInFile(this, f))
122+
) and (
123+
// Ignore comments on the same line as a preprocessor directive.
124+
not exists(Location l |
125+
l = this.getLocation() and
126+
preprocLine(l.getFile(), l.getStartLine())
127+
)
128+
)
95129
}
96130

97131
/**
@@ -133,6 +167,7 @@ class CommentBlock extends Comment {
133167

134168
predicate isCommentedOutCode() {
135169
not this.isDocumentation() and
170+
not this.getFile().(HeaderFile).noTopLevelCode() and
136171
this.numCodeLines().(float) / this.numLines().(float) > 0.5
137172
}
138173

cpp/ql/src/jsf/4.07 Header Files/AV Rule 35.ql

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,7 @@ where not hf instanceof IncludeGuardedHeader
133133
// Exclude files which contain no declaration entries or top level
134134
// declarations (e.g. just preprocessor directives; or non-top level
135135
// code).
136-
and (
137-
exists(DeclarationEntry de | de.getFile() = hf) or
138-
exists(Declaration d | d.getFile() = hf and d.isTopLevel()) or
139-
exists(UsingEntry ue | ue.getFile() = hf)
140-
)
136+
and not hf.noTopLevelCode()
141137
// Exclude files which look like they contain 'x-macros'
142138
and not hasXMacro(hf)
143139
// Exclude files which are always #imported.

cpp/ql/src/semmle/code/cpp/File.qll

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,20 @@ class HeaderFile extends File {
453453
exists(Include i | i.getIncludedFile() = this)
454454
}
455455

456+
/**
457+
* Holds if this header file does not contain any declaration entries or top level
458+
* declarations. For example it might be:
459+
* - a file containing only preprocessor directives and/or comments
460+
* - an empty file
461+
* - a file that contains non-top level code or data that's included in an
462+
* unusual way
463+
*/
464+
predicate noTopLevelCode()
465+
{
466+
not exists(DeclarationEntry de | de.getFile() = this) and
467+
not exists(Declaration d | d.getFile() = this and d.isTopLevel()) and
468+
not exists(UsingEntry ue | ue.getFile() = this)
469+
}
456470
}
457471

458472
/**

cpp/ql/test/query-tests/Documentation/CommentedOutCode/CommentedOutCode.expected

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
| test2.cpp:63:1:63:15 | // #pragma once | This comment appears to contain commented-out code |
99
| test2.cpp:65:1:65:17 | // # pragma once | This comment appears to contain commented-out code |
1010
| test2.cpp:67:1:67:19 | /*#error"myerror"*/ | This comment appears to contain commented-out code |
11+
| test2.cpp:91:1:95:2 | /*\n#ifdef MYMACRO\n\t// ...\n#endif // #ifdef MYMACRO\n*/ | This comment appears to contain commented-out code |
12+
| test2.cpp:107:21:107:43 | // #include "config2.h" | This comment appears to contain commented-out code |
13+
| test2.cpp:115:16:115:35 | /* #ifdef MYMACRO */ | This comment appears to contain commented-out code |
14+
| test2.cpp:117:1:117:24 | // commented_out_code(); | This comment appears to contain commented-out code |
15+
| test2.cpp:120:2:120:25 | // commented_out_code(); | This comment appears to contain commented-out code |
1116
| test.c:2:1:2:22 | // commented out code; | This comment appears to contain commented-out code |
1217
| test.c:4:1:7:8 | // some; | This comment appears to contain commented-out code |
1318
| test.c:9:1:13:8 | // also; | This comment appears to contain commented-out code |
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
2+
/* define if you want setting 1 */
3+
#define SETTING1
4+
5+
// define if you want setting 2
6+
//#define SETTING2
7+
8+
/* define if you want setting 3 */
9+
//#define SETTING3
10+
11+
/* define if you want setting 4 */
12+
/* #define SETTING4 */
13+
14+
#if defined(SETTING3) && defined(SETTING4)
15+
#error "can't have both SETTING3 and SETTING4"
16+
#endif
17+
18+
/* uncomment if you don't want setting 5 */
19+
/* #undef SETTING5 */

cpp/ql/test/query-tests/Documentation/CommentedOutCode/test2.cpp

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,3 +65,57 @@ void myFunction();
6565
// # pragma once
6666

6767
/*#error"myerror"*/
68+
69+
#ifdef MYMACRO
70+
71+
// ...
72+
73+
#endif // #ifdef MYMACRO
74+
75+
#if !defined(MYMACRO)
76+
77+
// ...
78+
79+
#else // #if !defined(MYMACRO)
80+
81+
// ...
82+
83+
#endif // #else #if !defined(MYMACRO)
84+
85+
#ifdef MYMACRO
86+
87+
// ...
88+
89+
#endif // #ifdef MYMACRO (comment)
90+
91+
/*
92+
#ifdef MYMACRO
93+
// ...
94+
#endif // #ifdef MYMACRO
95+
*/
96+
97+
98+
#ifdef MYMACRO1
99+
#ifdef MYMACRO2
100+
101+
// ...
102+
103+
// comment at end of block
104+
#endif // #ifdef MYMACRO2
105+
#endif // #ifdef MYMACRO1
106+
107+
#include "config.h" // #include "config2.h"
108+
109+
#ifdef MYMACRO
110+
111+
// ...
112+
113+
#endif /* #ifdef MYMACRO */
114+
115+
#error "error" /* #ifdef MYMACRO */
116+
117+
// commented_out_code();
118+
119+
#if 0
120+
// commented_out_code();
121+
#endif

0 commit comments

Comments
 (0)