mirror of
https://github.com/github/codeql.git
synced 2025-12-25 05:06:34 +01:00
69 lines
2.0 KiB
Plaintext
69 lines
2.0 KiB
Plaintext
/**
|
|
* @name Branching condition always evaluates to same value
|
|
* @description The condition of the branching statement always evaluates to the same value. This means that only one branch will ever be executed.
|
|
* @kind problem
|
|
* @id cpp/dead-code-condition
|
|
* @problem.severity warning
|
|
* @tags reliability
|
|
* external/cwe/cwe-561
|
|
*/
|
|
|
|
import cpp
|
|
|
|
predicate testAndBranch(Expr e, Stmt branch) {
|
|
exists(IfStmt ifstmt |
|
|
ifstmt.getCondition() = e and
|
|
(ifstmt.getThen() = branch or ifstmt.getElse() = branch)
|
|
)
|
|
or
|
|
exists(WhileStmt while |
|
|
while.getCondition() = e and
|
|
while.getStmt() = branch
|
|
)
|
|
}
|
|
|
|
predicate choice(StackVariable v, Stmt branch, string value) {
|
|
exists(AnalysedExpr e |
|
|
testAndBranch(e, branch) and
|
|
(
|
|
e.getNullSuccessor(v) = branch and value = "null"
|
|
or
|
|
e.getNonNullSuccessor(v) = branch and value = "non-null"
|
|
)
|
|
)
|
|
}
|
|
|
|
predicate guarded(StackVariable v, Stmt loopstart, AnalysedExpr child) {
|
|
choice(v, loopstart, _) and
|
|
loopstart.getChildStmt*() = child.getEnclosingStmt() and
|
|
(definition(v, child) or exists(child.getNullSuccessor(v)))
|
|
}
|
|
|
|
predicate addressLeak(Variable v, Stmt leak) {
|
|
exists(VariableAccess access |
|
|
v.getAnAccess() = access and
|
|
access.getEnclosingStmt() = leak and
|
|
access.isAddressOfAccess()
|
|
)
|
|
}
|
|
|
|
from StackVariable v, Stmt branch, AnalysedExpr cond, string context, string test, string testresult
|
|
where
|
|
choice(v, branch, context) and
|
|
forall(ControlFlowNode def | definition(v, def) and definitionReaches(def, cond) |
|
|
not guarded(v, branch, def)
|
|
) and
|
|
not cond.isDef(v) and
|
|
guarded(v, branch, cond) and
|
|
exists(cond.getNullSuccessor(v)) and
|
|
not addressLeak(v, branch.getChildStmt*()) and
|
|
(
|
|
cond.isNullCheck(v) and test = "null"
|
|
or
|
|
cond.isValidCheck(v) and test = "non-null"
|
|
) and
|
|
(if context = test then testresult = "succeed" else testresult = "fail")
|
|
select cond,
|
|
"Variable '" + v.getName() + "' is always " + context + ", this check will always " + testresult +
|
|
"."
|