Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion java/ql/consistency-queries/UnaryExpr.ql
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import java

from UnaryExpr ue
where
not exists(ue.getExpr())
not exists(ue.getOperand())
or
exists(Expr e, int i | e.isNthChildOf(ue, i) and i != 0)
select ue
2 changes: 1 addition & 1 deletion java/ql/examples/snippets/returnstatement.ql
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,5 @@
import java

from ReturnStmt r
where r.getResult() instanceof NullLiteral
where r.getExpr() instanceof NullLiteral
select r
6 changes: 3 additions & 3 deletions java/ql/examples/snippets/ternaryconditional.ql
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import java

from ConditionalExpr e
where
e.getTrueExpr().getType() != e.getFalseExpr().getType() and
not e.getTrueExpr().getType() instanceof NullType and
not e.getFalseExpr().getType() instanceof NullType
e.getThen().getType() != e.getElse().getType() and
not e.getThen().getType() instanceof NullType and
not e.getElse().getType() instanceof NullType
select e
12 changes: 12 additions & 0 deletions java/ql/lib/change-notes/2026-02-04-renames.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
category: deprecated
---
* Renamed the following predicates to increase uniformity across languages. The `getBody` predicate already existed on `LoopStmt`, but is now properly inherited.
- `UnaryExpr.getExpr` to `getOperand`.
- `ConditionalExpr.getTrueExpr` to `getThen`.
- `ConditionalExpr.getFalseExpr` to `getElse`.
- `ReturnStmt.getResult` to `getExpr`.
- `WhileStmt.getStmt` to `getBody`.
- `DoStmt.getStmt` to `getBody`.
- `ForStmt.getStmt` to `getBody`.
- `EnhancedForStmt.getStmt` to `getBody`.
8 changes: 4 additions & 4 deletions java/ql/lib/semmle/code/java/Constants.qll
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ module CalculateConstants<getBoolValSig/1 getBoolVal, getIntValSig/1 getIntVal>
boolean calculateBooleanValue(Expr e) {
// No casts relevant to booleans.
// `!` is the only unary operator that evaluates to a boolean.
result = getBoolVal(e.(LogNotExpr).getExpr()).booleanNot()
result = getBoolVal(e.(LogNotExpr).getOperand()).booleanNot()
or
// Handle binary expressions that have integer operands and a boolean result.
exists(BinaryExpr b, int left, int right |
Expand Down Expand Up @@ -115,11 +115,11 @@ module CalculateConstants<getBoolValSig/1 getBoolVal, getIntValSig/1 getIntVal>
else result = val
)
or
result = getIntVal(e.(PlusExpr).getExpr())
result = getIntVal(e.(PlusExpr).getOperand())
or
result = -getIntVal(e.(MinusExpr).getExpr())
result = -getIntVal(e.(MinusExpr).getOperand())
or
result = getIntVal(e.(BitNotExpr).getExpr()).bitNot()
result = getIntVal(e.(BitNotExpr).getOperand()).bitNot()
or
// No `int` value for `LogNotExpr`.
exists(BinaryExpr b, int v1, int v2 |
Expand Down
20 changes: 10 additions & 10 deletions java/ql/lib/semmle/code/java/ControlFlowGraph.qll
Original file line number Diff line number Diff line change
Expand Up @@ -827,7 +827,7 @@ private module ControlFlowGraphImpl {
index = 1 and result = e.getRightOperand()
)
or
index = 0 and result = this.(UnaryExpr).getExpr()
index = 0 and result = this.(UnaryExpr).getOperand()
or
index = 0 and result = this.(CastingExpr).getExpr()
or
Expand All @@ -849,7 +849,7 @@ private module ControlFlowGraphImpl {
or
index = 0 and result = this.(ClassExpr).getExpr()
or
index = 0 and result = this.(ReturnStmt).getResult()
index = 0 and result = this.(ReturnStmt).getExpr()
or
index = 0 and result = this.(ThrowStmt).getExpr()
or
Expand Down Expand Up @@ -1044,7 +1044,7 @@ private module ControlFlowGraphImpl {
or
// The last node of a `LogNotExpr` is in its sub-expression with an inverted boolean completion
// (or a `normalCompletion`).
exists(Completion subcompletion | last(n.(LogNotExpr).getExpr(), last, subcompletion) |
exists(Completion subcompletion | last(n.(LogNotExpr).getOperand(), last, subcompletion) |
subcompletion = NormalCompletion() and
completion = NormalCompletion() and
not inBooleanContext(n)
Expand Down Expand Up @@ -1356,7 +1356,7 @@ private module ControlFlowGraphImpl {
(
result = first(n.asExpr().(AndLogicalExpr).getLeftOperand()) or
result = first(n.asExpr().(OrLogicalExpr).getLeftOperand()) or
result = first(n.asExpr().(LogNotExpr).getExpr()) or
result = first(n.asExpr().(LogNotExpr).getOperand()) or
result = first(n.asExpr().(ConditionalExpr).getCondition())
)
or
Expand Down Expand Up @@ -1427,7 +1427,7 @@ private module ControlFlowGraphImpl {
condentry = first(for.getCondition())
or
// ...or the body if the for doesn't include a condition.
not exists(for.getCondition()) and condentry = first(for.getStmt())
not exists(for.getCondition()) and condentry = first(for.getBody())
|
// From the entry point, which is the for statement itself, control goes to either the first init expression...
n.asStmt() = for and result = first(for.getInit(0)) and completion = NormalCompletion()
Expand All @@ -1448,7 +1448,7 @@ private module ControlFlowGraphImpl {
// The true-successor of the condition is the body of the for loop.
last(for.getCondition(), n, completion) and
completion = BooleanCompletion(true, _) and
result = first(for.getStmt())
result = first(for.getBody())
or
// The updates execute sequentially, after which control is transferred to the condition.
exists(int i | last(for.getUpdate(i), n, completion) and completion = NormalCompletion() |
Expand All @@ -1458,7 +1458,7 @@ private module ControlFlowGraphImpl {
)
or
// The back edge of the loop: control goes to either the first update or the condition if no updates exist.
last(for.getStmt(), n, completion) and
last(for.getBody(), n, completion) and
continues(completion, for) and
(
result = first(for.getUpdate(0))
Expand All @@ -1479,11 +1479,11 @@ private module ControlFlowGraphImpl {
or
// ...and then control goes to the body of the loop.
n.asExpr() = for.getVariable() and
result = first(for.getStmt()) and
result = first(for.getBody()) and
completion = NormalCompletion()
or
// Finally, the back edge of the loop goes to reassign the variable.
last(for.getStmt(), n, completion) and
last(for.getBody(), n, completion) and
continues(completion, for) and
result.asExpr() = for.getVariable()
)
Expand All @@ -1492,7 +1492,7 @@ private module ControlFlowGraphImpl {
result = first(n.asStmt().(WhileStmt).getCondition()) and completion = NormalCompletion()
or
// ...and do-while loops start at the body.
result = first(n.asStmt().(DoStmt).getStmt()) and completion = NormalCompletion()
result = first(n.asStmt().(DoStmt).getBody()) and completion = NormalCompletion()
or
exists(LoopStmt loop | loop instanceof WhileStmt or loop instanceof DoStmt |
// Control goes from the condition via a true-completion to the body...
Expand Down
2 changes: 1 addition & 1 deletion java/ql/lib/semmle/code/java/Conversions.qll
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class AssignmentConversionContext extends ConversionSite {
class ReturnConversionSite extends ConversionSite {
ReturnStmt r;

ReturnConversionSite() { this = r.getResult() }
ReturnConversionSite() { this = r.getExpr() }

override Type getConversionTarget() { result = r.getEnclosingCallable().getReturnType() }

Expand Down
63 changes: 43 additions & 20 deletions java/ql/lib/semmle/code/java/Expr.qll
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ class Expr extends ExprParent, @expr {
if this instanceof CastingExpr or this instanceof NotNullExpr
then
result = this.(CastingExpr).getExpr().getUnderlyingExpr() or
result = this.(NotNullExpr).getExpr().getUnderlyingExpr()
result = this.(NotNullExpr).getOperand().getUnderlyingExpr()
else result = this
}
}
Expand Down Expand Up @@ -144,13 +144,13 @@ class CompileTimeConstantExpr extends Expr {
this.(CastingExpr).getExpr().isCompileTimeConstant()
or
// The unary operators `+`, `-`, `~`, and `!` (but not `++` or `--`).
this.(PlusExpr).getExpr().isCompileTimeConstant()
this.(PlusExpr).getOperand().isCompileTimeConstant()
or
this.(MinusExpr).getExpr().isCompileTimeConstant()
this.(MinusExpr).getOperand().isCompileTimeConstant()
or
this.(BitNotExpr).getExpr().isCompileTimeConstant()
this.(BitNotExpr).getOperand().isCompileTimeConstant()
or
this.(LogNotExpr).getExpr().isCompileTimeConstant()
this.(LogNotExpr).getOperand().isCompileTimeConstant()
or
// The multiplicative operators `*`, `/`, and `%`,
// the additive operators `+` and `-`,
Expand All @@ -166,8 +166,8 @@ class CompileTimeConstantExpr extends Expr {
// The ternary conditional operator ` ? : `.
exists(ConditionalExpr e | this = e |
e.getCondition().isCompileTimeConstant() and
e.getTrueExpr().isCompileTimeConstant() and
e.getFalseExpr().isCompileTimeConstant()
e.getThen().isCompileTimeConstant() and
e.getElse().isCompileTimeConstant()
)
or
// Access to a final variable initialized by a compile-time constant.
Expand Down Expand Up @@ -943,7 +943,7 @@ class LogicExpr extends Expr {
/** Gets an operand of this logical expression. */
Expr getAnOperand() {
this.(BinaryExpr).getAnOperand() = result or
this.(UnaryExpr).getExpr() = result
this.(UnaryExpr).getOperand() = result
}
}

Expand Down Expand Up @@ -1039,8 +1039,15 @@ class ReferenceEqualityTest extends EqualityTest {

/** A common super-class that represents unary operator expressions. */
class UnaryExpr extends Expr, @unaryexpr {
/**
* DEPRECATED: Use getOperand() instead.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: backticks

*
* Gets the operand expression.
*/
deprecated Expr getExpr() { result.getParent() = this }

/** Gets the operand expression. */
Expr getExpr() { result.getParent() = this }
Expr getOperand() { result.getParent() = this }
}

/**
Expand Down Expand Up @@ -1305,7 +1312,7 @@ class LambdaExpr extends FunctionalExpr, @lambdaexpr {

/** Gets the body of this lambda expression, if it is an expression. */
Expr getExprBody() {
this.hasExprBody() and result = this.asMethod().getBody().getAChild().(ReturnStmt).getResult()
this.hasExprBody() and result = this.asMethod().getBody().getAChild().(ReturnStmt).getExpr()
}

/** Gets the body of this lambda expression, if it is a statement. */
Expand Down Expand Up @@ -1340,7 +1347,7 @@ class MemberRefExpr extends FunctionalExpr, @memberref {
exists(Stmt stmt |
stmt = this.asMethod().getBody().(SingletonBlock).getStmt() and
(
result = stmt.(ReturnStmt).getResult()
result = stmt.(ReturnStmt).getExpr()
or
// Note: Currently never an ExprStmt, but might change once https://github.com/github/codeql/issues/3605 is fixed
result = stmt.(ExprStmt).getExpr()
Expand Down Expand Up @@ -1456,27 +1463,43 @@ class ConditionalExpr extends Expr, @conditionalexpr {
/** Gets the condition of this conditional expression. */
Expr getCondition() { result.isNthChildOf(this, 0) }

/**
* DEPRECATED: Use getThen() instead.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

*
* Gets the expression that is evaluated if the condition of this
* conditional expression evaluates to `true`.
*/
deprecated Expr getTrueExpr() { result.isNthChildOf(this, 1) }

/**
* DEPRECATED: Use getElse() instead.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same

*
* Gets the expression that is evaluated if the condition of this
* conditional expression evaluates to `false`.
*/
deprecated Expr getFalseExpr() { result.isNthChildOf(this, 2) }

/**
* Gets the expression that is evaluated if the condition of this
* conditional expression evaluates to `true`.
*/
Expr getTrueExpr() { result.isNthChildOf(this, 1) }
Expr getThen() { result.isNthChildOf(this, 1) }

/**
* Gets the expression that is evaluated if the condition of this
* conditional expression evaluates to `false`.
*/
Expr getFalseExpr() { result.isNthChildOf(this, 2) }
Expr getElse() { result.isNthChildOf(this, 2) }

/**
* Gets the expression that is evaluated by the specific branch of this
* conditional expression. If `true` that is `getTrueExpr()`, if `false`
* it is `getFalseExpr()`.
* conditional expression. If `true` that is `getThen()`, if `false`
* it is `getElse()`.
*/
Expr getBranchExpr(boolean branch) {
branch = true and result = this.getTrueExpr()
branch = true and result = this.getThen()
or
branch = false and result = this.getFalseExpr()
branch = false and result = this.getElse()
}

/**
Expand Down Expand Up @@ -1773,14 +1796,14 @@ class VariableUpdate extends Expr {
VariableUpdate() {
this.(Assignment).getDest() instanceof VarAccess or
this instanceof LocalVariableDeclExpr or
this.(UnaryAssignExpr).getExpr() instanceof VarAccess
this.(UnaryAssignExpr).getOperand() instanceof VarAccess
}

/** Gets the destination of this variable update. */
Variable getDestVar() {
result.getAnAccess() = this.(Assignment).getDest() or
result = this.(LocalVariableDeclExpr).getVariable() or
result.getAnAccess() = this.(UnaryAssignExpr).getExpr()
result.getAnAccess() = this.(UnaryAssignExpr).getOperand()
}
}

Expand Down Expand Up @@ -1970,7 +1993,7 @@ class VarAccess extends Expr, @varaccess {
*/
predicate isVarWrite() {
exists(Assignment a | a.getDest() = this) or
exists(UnaryAssignExpr e | e.getExpr() = this)
exists(UnaryAssignExpr e | e.getOperand() = this)
}

/**
Expand Down
4 changes: 2 additions & 2 deletions java/ql/lib/semmle/code/java/Member.qll
Original file line number Diff line number Diff line change
Expand Up @@ -680,13 +680,13 @@ class GetterMethod extends Method {
GetterMethod() {
this.hasNoParameters() and
exists(ReturnStmt s, Field f | s = this.getBody().(SingletonBlock).getStmt() |
s.getResult() = f.getAnAccess()
s.getExpr() = f.getAnAccess()
)
}

/** Gets the field whose value is returned by this getter method. */
Field getField() {
exists(ReturnStmt r | r.getEnclosingCallable() = this | r.getResult() = result.getAnAccess())
exists(ReturnStmt r | r.getEnclosingCallable() = this | r.getExpr() = result.getAnAccess())
}
}

Expand Down
Loading
Loading