Skip to content

Commit 0bb6ff5

Browse files
authored
Merge pull request #21466 from owen-mc/go/add-nil-helper-predicate
Go: Add and use `exprRefersToNil` predicate
2 parents f2e7dca + c271755 commit 0bb6ff5

File tree

6 files changed

+13
-10
lines changed

6 files changed

+13
-10
lines changed

go/ql/lib/semmle/go/Expr.qll

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2035,6 +2035,9 @@ class ConstantName extends ValueName {
20352035
override string getAPrimaryQlClass() { result = "ConstantName" }
20362036
}
20372037

2038+
/** Holds if `e` is an expression that refers to the `nil` constant. */
2039+
predicate exprRefersToNil(Expr e) { e.(ConstantName).getTarget() = Builtin::nil() }
2040+
20382041
/**
20392042
* A name referring to a variable.
20402043
*
@@ -2175,7 +2178,7 @@ private predicate isTypeExprTopDown(Expr e) {
21752178
or
21762179
e = any(TypeSwitchStmt s).getACase().getExpr(_) and
21772180
// special case: `nil` is allowed in a type case but isn't a type
2178-
not e = Builtin::nil().getAReference()
2181+
not exprRefersToNil(e)
21792182
or
21802183
e = any(SelectorExpr sel | isTypeExprTopDown(sel)).getBase()
21812184
or

go/ql/lib/semmle/go/dataflow/Properties.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ class Property extends TProperty {
2222
isTrue = eq.getPolarity().booleanXor(e.getBoolValue().booleanXor(outcome))
2323
or
2424
this = IsNil(isTrue) and
25-
e = Builtin::nil().getAReference() and
25+
exprRefersToNil(e) and
2626
isTrue = eq.getPolarity().booleanXor(outcome).booleanNot()
2727
)
2828
or

go/ql/lib/semmle/go/dataflow/internal/DataFlowUtil.qll

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -560,7 +560,7 @@ private predicate onlyPossibleReturnOfBool(FuncDecl fd, FunctionOutput res, Node
560560
*/
561561
predicate possiblyReturnsNonNil(FuncDecl fd, FunctionOutput res, Node ret) {
562562
ret = res.getEntryNode(fd) and
563-
not ret.asExpr() = Builtin::nil().getAReference()
563+
not exprRefersToNil(ret.asExpr())
564564
}
565565

566566
/**
@@ -570,7 +570,7 @@ predicate possiblyReturnsNonNil(FuncDecl fd, FunctionOutput res, Node ret) {
570570
private predicate onlyPossibleReturnOfNonNil(FuncDecl fd, FunctionOutput res, Node ret) {
571571
possiblyReturnsNonNil(fd, res, ret) and
572572
forall(Node otherRet | otherRet = res.getEntryNode(fd) and otherRet != ret |
573-
otherRet.asExpr() = Builtin::nil().getAReference()
573+
exprRefersToNil(otherRet.asExpr())
574574
)
575575
}
576576

@@ -609,7 +609,7 @@ private predicate isCertainlyNotNil(DataFlow::Node node) {
609609
*/
610610
private predicate onlyPossibleReturnOfNil(FuncDecl fd, FunctionOutput res, DataFlow::Node ret) {
611611
ret = res.getEntryNode(fd) and
612-
ret.asExpr() = Builtin::nil().getAReference() and
612+
exprRefersToNil(ret.asExpr()) and
613613
forall(DataFlow::Node otherRet | otherRet = res.getEntryNode(fd) and otherRet != ret |
614614
isCertainlyNotNil(otherRet)
615615
)

go/ql/lib/semmle/go/dataflow/internal/TaintTrackingUtil.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ predicate functionEnsuresInputIsConstant(
418418
forex(DataFlow::Node ret, IR::ReturnInstruction ri |
419419
ret = outp.getEntryNode(fd) and
420420
ri.getReturnStmt().getAnExpr() = ret.asExpr() and
421-
ret.asExpr() = Builtin::nil().getAReference()
421+
exprRefersToNil(ret.asExpr())
422422
|
423423
DataFlow::localFlow(inp.getExitNode(fd), _) and
424424
mustPassConstantCaseTestToReach(ri, inp.getExitNode(fd))

go/ql/src/RedundantCode/UnreachableStatement.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ ControlFlow::Node nonGuardPredecessor(ControlFlow::Node nd) {
2626
* Matches if `retval` is a constant or a struct composed wholly of constants.
2727
*/
2828
predicate isAllowedReturnValue(Expr retval) {
29-
retval = Builtin::nil().getAReference()
29+
exprRefersToNil(retval)
3030
or
3131
retval = Builtin::true_().getAReference()
3232
or

go/ql/src/experimental/CWE-203/Timing.ql

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ private class SensitiveStringCompareSink extends Sink {
3636
not op1 = nonSensitiveOperand and
3737
not (
3838
// Comparisons with `nil` should be excluded.
39-
nonSensitiveOperand = Builtin::nil().getAReference()
39+
exprRefersToNil(nonSensitiveOperand)
4040
or
4141
// Comparisons with empty string should also be excluded.
4242
nonSensitiveOperand.getStringValue().length() = 0
@@ -60,7 +60,7 @@ private class SensitiveCompareSink extends Sink {
6060
not op1 = op2 and
6161
not (
6262
// Comparisons with `nil` should be excluded.
63-
op2 = Builtin::nil().getAReference()
63+
exprRefersToNil(op2)
6464
or
6565
// Comparisons with empty string should also be excluded.
6666
op2.getStringValue().length() = 0
@@ -85,7 +85,7 @@ private class SensitiveStringSink extends Sink {
8585
not op1 = op2 and
8686
not (
8787
// Comparisons with `nil` should be excluded.
88-
op2 = Builtin::nil().getAReference()
88+
exprRefersToNil(op2)
8989
or
9090
// Comparisons with empty string should also be excluded.
9191
op2.getStringValue().length() = 0

0 commit comments

Comments
 (0)