Skip to content

Commit 4b5aa14

Browse files
committed
C++: Implement Function::hasErrors()
1 parent 60abea1 commit 4b5aa14

File tree

4 files changed

+17
-2
lines changed

4 files changed

+17
-2
lines changed

cpp/ql/lib/semmle/code/cpp/Function.qll

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -500,6 +500,14 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
500500
* Gets the nearest enclosing AccessHolder.
501501
*/
502502
override AccessHolder getEnclosingAccessHolder() { result = this.getDeclaringType() }
503+
504+
/**
505+
* Holds if this function has extraction errors that create an `ErrorExpr`.
506+
*/
507+
predicate hasErrors() {
508+
// Exclude allocator call arguments because they are are always extracted as `ErrorExpr`.
509+
exists(ErrorExpr e | e.getEnclosingFunction() = this and not e.isFirstAllocatorCallArgument())
510+
}
503511
}
504512

505513
pragma[noinline]

cpp/ql/lib/semmle/code/cpp/exprs/Expr.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,13 @@ class ErrorExpr extends Expr, @errorexpr {
744744
override string toString() { result = "<error expr>" }
745745

746746
override string getAPrimaryQlClass() { result = "ErrorExpr" }
747+
748+
/**
749+
* Holds if this error expression is the first argument to a `new` allocation call.
750+
*/
751+
predicate isFirstAllocatorCallArgument() {
752+
this = any(NewOrNewArrayExpr new).getAllocatorCall().getArgument(0)
753+
}
747754
}
748755

749756
/**

cpp/ql/src/Likely Bugs/Memory Management/UninitializedLocal.ql

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -89,5 +89,6 @@ from
8989
where
9090
conf.hasFlowPath(source, sink) and
9191
isSinkImpl(sink.getInstruction(), va) and
92-
v = va.getTarget()
92+
v = va.getTarget() and
93+
not v.getFunction().hasErrors()
9394
select va, source, sink, "The variable $@ may not be initialized at this access.", v, v.getName()

cpp/ql/test/query-tests/Security/CWE/CWE-457/semmle/tests/UninitializedLocal.expected

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ nodes
1616
| test.cpp:472:6:472:6 | definition of x | semmle.label | definition of x |
1717
| test.cpp:479:6:479:6 | definition of x | semmle.label | definition of x |
1818
#select
19-
| errors.cpp:6:10:6:10 | x | errors.cpp:4:7:4:7 | definition of x | errors.cpp:4:7:4:7 | definition of x | The variable $@ may not be initialized at this access. | errors.cpp:4:7:4:7 | x | x |
2019
| errors.cpp:14:18:14:18 | x | errors.cpp:13:7:13:7 | definition of x | errors.cpp:13:7:13:7 | definition of x | The variable $@ may not be initialized at this access. | errors.cpp:13:7:13:7 | x | x |
2120
| test.cpp:12:6:12:8 | foo | test.cpp:11:6:11:8 | definition of foo | test.cpp:11:6:11:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:11:6:11:8 | foo | foo |
2221
| test.cpp:113:6:113:8 | foo | test.cpp:111:6:111:8 | definition of foo | test.cpp:111:6:111:8 | definition of foo | The variable $@ may not be initialized at this access. | test.cpp:111:6:111:8 | foo | foo |

0 commit comments

Comments
 (0)