Skip to content

Commit dad3413

Browse files
committed
C++: Add more tests.
1 parent d15e388 commit dad3413

File tree

4 files changed

+139
-1
lines changed

4 files changed

+139
-1
lines changed
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
| test.cpp:370:5:370:7 | Call: call to chk | 'call to testNotNull1:true' |
2+
| test.cpp:370:5:370:7 | Call: call to chk | 'p:not null' |
3+
| test.cpp:372:5:372:7 | Call: call to chk | 'call to testNotNull1:false' |
4+
| test.cpp:372:5:372:7 | Call: call to chk | p:null |
5+
| test.cpp:376:5:376:7 | Call: call to chk | 'call to testNotNull2:true' |
6+
| test.cpp:378:5:378:7 | Call: call to chk | 'call to testNotNull2:false' |
7+
| test.cpp:382:5:382:7 | Call: call to chk | '0 == call to getNumOrDefault:true' |
8+
| test.cpp:382:5:382:7 | Call: call to chk | 'call to getNumOrDefault:0' |
9+
| test.cpp:384:5:384:7 | Call: call to chk | '0 == call to getNumOrDefault:false' |
10+
| test.cpp:384:5:384:7 | Call: call to chk | 'call to getNumOrDefault:not 0' |
11+
| test.cpp:384:5:384:7 | Call: call to chk | 'i:not null' |
12+
| test.cpp:388:5:388:7 | Call: call to chk | '0 == call to returnAIfNoneAreNull:true' |
13+
| test.cpp:388:5:388:7 | Call: call to chk | 'call to returnAIfNoneAreNull:0' |
14+
| test.cpp:390:5:390:7 | Call: call to chk | '0 == call to returnAIfNoneAreNull:false' |
15+
| test.cpp:390:5:390:7 | Call: call to chk | 'call to returnAIfNoneAreNull:not 0' |
16+
| test.cpp:395:7:395:9 | Call: call to chk | 'call to testEnumWrapper:1' |
17+
| test.cpp:395:7:395:9 | Call: call to chk | 'call to testEnumWrapper=SUCCESS:true' |
18+
| test.cpp:395:7:395:9 | Call: call to chk | b:true |
19+
| test.cpp:398:7:398:9 | Call: call to chk | 'call to testEnumWrapper:2' |
20+
| test.cpp:398:7:398:9 | Call: call to chk | 'call to testEnumWrapper=FAILURE:true' |
21+
| test.cpp:398:7:398:9 | Call: call to chk | b:false |
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import cpp
2+
import semmle.code.cpp.controlflow.Guards
3+
import codeql.util.Boolean
4+
5+
bindingset[s]
6+
string escape(string s) { if s.matches("% %") then result = "'" + s + "'" else result = s }
7+
8+
Expr getUnconverted(Element e) {
9+
not e instanceof Expr and
10+
result = e
11+
or
12+
result = e.(Expr).getUnconverted()
13+
}
14+
15+
string ppGuard(IRGuardCondition g, GuardValue val) {
16+
exists(BinaryOperation bin |
17+
bin = getUnconverted(g.getAst()) and
18+
result =
19+
bin.getLeftOperand() + " " + bin.getOperator() + " " + bin.getRightOperand() + ":" + val
20+
)
21+
or
22+
exists(SwitchCase cc, Expr s, string value |
23+
cc = g.getAst() and
24+
cc.getExpr() = s and
25+
result = cc.getSwitchStmt().getExpr() + "=" + value + ":" + val
26+
|
27+
value = cc.getExpr().toString()
28+
or
29+
cc.isDefault() and value = "default"
30+
)
31+
}
32+
33+
query predicate guarded(CallInstruction c, string guard) {
34+
c.getStaticCallTarget().hasName("chk") and
35+
exists(IRGuardCondition g, IRBlock bb, GuardValue val |
36+
g.valueControls(bb, val) and
37+
c.getBlock() = bb
38+
|
39+
guard = escape(ppGuard(g, val))
40+
or
41+
not exists(ppGuard(g, val)) and
42+
guard = escape(getUnconverted(g.getAst()).toString() + ":" + val)
43+
)
44+
}
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
query: GuardsInline.ql
2+
postprocess: utils/test/InlineExpectationsTestQuery.ql

cpp/ql/test/library-tests/controlflow/guards/test.cpp

Lines changed: 72 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,4 +337,75 @@ void test_constant_value_and_case_range(bool b)
337337
// should not be guarded by `foo() = 40..50`
338338
use(x);
339339
}
340-
}
340+
}
341+
342+
void chk();
343+
344+
bool testNotNull1(void* input) {
345+
return input != nullptr;
346+
}
347+
348+
bool testNotNull2(void* input) {
349+
if (input == nullptr) return false;
350+
return true;
351+
}
352+
353+
int getNumOrDefault(int* number) {
354+
return number == nullptr ? 0 : *number;
355+
}
356+
357+
char returnAIfNoneAreNull(char* s1, char* s2) {
358+
if (!s1 || !s2) return '\0';
359+
return 'a';
360+
}
361+
362+
enum class Status { SUCCESS = 1, FAILURE = 2 };
363+
364+
Status testEnumWrapper(bool flag) {
365+
return flag ? Status::SUCCESS : Status::FAILURE;
366+
}
367+
368+
void testWrappers(void* p, int* i, char* s, bool b) {
369+
if (testNotNull1(p)) {
370+
chk(); // $ guarded='p:not null' guarded='call to testNotNull1:true'
371+
} else {
372+
chk(); // $ guarded=p:null guarded='call to testNotNull1:false'
373+
}
374+
375+
if (testNotNull2(p)) {
376+
chk(); // $ guarded='call to testNotNull2:true' MISSING: guarded='p:not null'
377+
} else {
378+
chk(); // $ guarded='call to testNotNull2:false'
379+
}
380+
381+
if (0 == getNumOrDefault(i)) {
382+
chk(); // $ guarded='0 == call to getNumOrDefault:true' guarded='call to getNumOrDefault:0'
383+
} else {
384+
chk(); // $ guarded='0 == call to getNumOrDefault:false' guarded='call to getNumOrDefault:not 0' guarded='i:not null'
385+
}
386+
387+
if ('\0' == returnAIfNoneAreNull(s, "suffix")) {
388+
chk(); // $ guarded='0 == call to returnAIfNoneAreNull:true' guarded='call to returnAIfNoneAreNull:0'
389+
} else {
390+
chk(); // $ guarded='0 == call to returnAIfNoneAreNull:false' guarded='call to returnAIfNoneAreNull:not 0' MISSING: guarded='s:not null'
391+
}
392+
393+
switch (testEnumWrapper(b)) {
394+
case Status::SUCCESS:
395+
chk(); // $ guarded='call to testEnumWrapper=SUCCESS:true' guarded='call to testEnumWrapper:1' guarded=b:true
396+
break;
397+
case Status::FAILURE:
398+
chk(); // $ guarded='call to testEnumWrapper=FAILURE:true' guarded='call to testEnumWrapper:2' guarded=b:false
399+
break;
400+
}
401+
}
402+
403+
void ensureNotNull(void* o) {
404+
if (!o) throw 42;
405+
}
406+
407+
void testExceptionWrapper(void* s) {
408+
chk(); // nothing guards here
409+
ensureNotNull(s);
410+
chk(); // $ MISSING: guarded='call to ensureNotNull:no exception' guarded='s:not null'
411+
}

0 commit comments

Comments
 (0)