Skip to content

Commit 8888ee9

Browse files
authored
Merge pull request #16149 from codeqlhelper/main
C++: Improvements to reduce false alarms
2 parents 69d8fa6 + e1884c1 commit 8888ee9

File tree

6 files changed

+57
-2
lines changed

6 files changed

+57
-2
lines changed

cpp/ql/src/Critical/GlobalUseBeforeInit.ql

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ predicate useFunc(GlobalVariable v, Function f) {
3131
}
3232

3333
predicate uninitialisedBefore(GlobalVariable v, Function f) {
34-
f.hasGlobalName("main")
34+
f.hasGlobalName("main") and
35+
not initialisedAtDeclaration(v) and
36+
not isStdlibVariable(v)
3537
or
3638
exists(Call call, Function g |
3739
uninitialisedBefore(v, g) and
@@ -98,10 +100,16 @@ predicate callReaches(Call call, ControlFlowNode successor) {
98100
)
99101
}
100102

103+
/** Holds if `v` has an initializer. */
104+
predicate initialisedAtDeclaration(GlobalVariable v) { exists(v.getInitializer()) }
105+
106+
/** Holds if `v` is a global variable that does not need to be initialized. */
107+
predicate isStdlibVariable(GlobalVariable v) { v.hasGlobalName(["stdin", "stdout", "stderr"]) }
108+
101109
from GlobalVariable v, Function f
102110
where
103111
uninitialisedBefore(v, f) and
104112
useFunc(v, f)
105113
select f,
106-
"The variable '" + v.getName() +
114+
"The variable '" + v.getName() + "'" +
107115
" is used in this function but may not be initialized when it is called."

cpp/ql/src/Critical/InconsistentNullnessTesting.ql

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import cpp
1515
from StackVariable v, ControlFlowNode def, VariableAccess checked, VariableAccess unchecked
1616
where
1717
checked = v.getAnAccess() and
18+
// The check can often be in a macro for handling exception
19+
not checked.isInMacroExpansion() and
1820
dereferenced(checked) and
1921
unchecked = v.getAnAccess() and
2022
dereferenced(unchecked) and
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The "Global variable may be used before initialization" query (`cpp/global-use-before-init`) no longer raises an alert on global variables that are initialized when they are declared.
5+
* The "Inconsistent null check of pointer" query (`cpp/inconsistent-nullness-testing`) query no longer raises an alert when the guarded check is in a macro expansion.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| test.cpp:27:5:27:6 | f1 | The variable 'b' is used in this function but may not be initialized when it is called. |
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Critical/GlobalUseBeforeInit.ql
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
typedef __builtin_va_list va_list;
2+
typedef struct {} FILE;
3+
4+
extern FILE * stdin;
5+
extern FILE * stdout;
6+
extern FILE * stderr;
7+
8+
#define va_start(args, fmt) __builtin_va_start(args,fmt)
9+
#define va_end(args) __builtin_va_end(args);
10+
11+
int vfprintf (FILE *, const char *, va_list);
12+
13+
int a = 1;
14+
int b;
15+
16+
int my_printf(const char * fmt, ...)
17+
{
18+
va_list vl;
19+
int ret;
20+
va_start(vl, fmt);
21+
ret = vfprintf(stdout, fmt, vl);
22+
ret = vfprintf(stderr, fmt, vl);
23+
va_end(vl);
24+
return ret;
25+
}
26+
27+
int f1()
28+
{
29+
my_printf("%d\n", a + 2);
30+
my_printf("%d\n", b + 2); // BAD
31+
return 0;
32+
}
33+
34+
int main()
35+
{
36+
int b = f1();
37+
return 0;
38+
}

0 commit comments

Comments
 (0)