Skip to content

Commit 19d6f66

Browse files
authored
Merge pull request #19676 from mrigankpawagi/patch-1
Fixes in cpp/global-use-before-init
2 parents 7c2fd28 + fe24cc8 commit 19d6f66

File tree

4 files changed

+40
-8
lines changed

4 files changed

+40
-8
lines changed

cpp/ql/src/Critical/GlobalUseBeforeInit.ql

Lines changed: 24 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,29 @@ predicate initFunc(GlobalVariable v, Function f) {
2121
)
2222
}
2323

24+
/** Holds if `v` has an initializer in function `f` that dominates `node`. */
25+
predicate dominatingInitInFunc(GlobalVariable v, Function f, ControlFlowNode node) {
26+
exists(VariableAccess initAccess |
27+
v.getAnAccess() = initAccess and
28+
initAccess.isUsedAsLValue() and
29+
initAccess.getEnclosingFunction() = f and
30+
dominates(initAccess, node)
31+
)
32+
}
33+
34+
predicate safeAccess(VariableAccess access) {
35+
// it is safe if the variable access is part of a `sizeof` expression
36+
exists(SizeofExprOperator e | e.getAChild*() = access)
37+
}
38+
2439
predicate useFunc(GlobalVariable v, Function f) {
2540
exists(VariableAccess access |
2641
v.getAnAccess() = access and
2742
access.isRValue() and
28-
access.getEnclosingFunction() = f
29-
) and
30-
not initFunc(v, f)
43+
access.getEnclosingFunction() = f and
44+
not safeAccess(access) and
45+
not dominatingInitInFunc(v, f, access)
46+
)
3147
}
3248

3349
predicate uninitialisedBefore(GlobalVariable v, Function f) {
@@ -38,12 +54,14 @@ predicate uninitialisedBefore(GlobalVariable v, Function f) {
3854
exists(Call call, Function g |
3955
uninitialisedBefore(v, g) and
4056
call.getEnclosingFunction() = g and
41-
(not functionInitialises(f, v) or locallyUninitialisedAt(v, call)) and
57+
(not functionInitialises(g, v) or locallyUninitialisedAt(v, call)) and
4258
resolvedCall(call, f)
4359
)
4460
}
4561

4662
predicate functionInitialises(Function f, GlobalVariable v) {
63+
initFunc(v, f)
64+
or
4765
exists(Call call |
4866
call.getEnclosingFunction() = f and
4967
initialisedBy(v, call)
@@ -60,7 +78,8 @@ predicate locallyUninitialisedAt(GlobalVariable v, Call call) {
6078
exists(Call mid |
6179
locallyUninitialisedAt(v, mid) and not initialisedBy(v, mid) and callPair(mid, call)
6280
)
63-
)
81+
) and
82+
not dominatingInitInFunc(v, call.getEnclosingFunction(), call)
6483
}
6584

6685
predicate initialisedBy(GlobalVariable v, Call call) {
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Fixed a number of false positives and false negatives in `cpp/global-use-before-init`. Note that this query is not part of any of the default query suites.
Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
| test.cpp:27:5:27:6 | f1 | The variable $@ is used in this function but may not be initialized when it is called. | test.cpp:14:5:14:5 | b | b |
1+
| test.cpp:28:5:28:6 | f1 | The variable $@ is used in this function but may not be initialized when it is called. | test.cpp:14:5:14:5 | b | b |
2+
| test.cpp:39:5:39:8 | main | The variable $@ is used in this function but may not be initialized when it is called. | test.cpp:14:5:14:5 | b | b |

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ int vfprintf (FILE *, const char *, va_list);
1212

1313
int a = 1;
1414
int b;
15+
int *c;
1516

1617
int my_printf(const char * fmt, ...)
1718
{
@@ -31,8 +32,15 @@ int f1()
3132
return 0;
3233
}
3334

35+
void f2() {
36+
my_printf("%d\n", b); // GOOD
37+
}
38+
3439
int main()
3540
{
36-
int b = f1();
41+
unsigned size = sizeof(*c); // GOOD
42+
my_printf("%d\n", b); // BAD
43+
b = f1();
44+
f2();
3745
return 0;
38-
}
46+
}

0 commit comments

Comments
 (0)