Java: Extend library support for switch expressions.

This commit is contained in:
Anders Schack-Mulligen
2020-05-14 15:40:26 +02:00
parent 8ce9c9d57e
commit 0aad24e6db
15 changed files with 77 additions and 31 deletions

View File

@@ -579,6 +579,8 @@ private module ControlFlowGraphImpl {
n instanceof Stmt and
not n instanceof PostOrderNode and
not n instanceof SynchronizedStmt
or
result = n and n instanceof SwitchExpr
}
/**

View File

@@ -1051,6 +1051,18 @@ class MemberRefExpr extends FunctionalExpr, @memberref {
override string toString() { result = "...::..." }
}
/** A conditional expression or a `switch` expression. */
class ChooseExpr extends Expr {
ChooseExpr() { this instanceof ConditionalExpr or this instanceof SwitchExpr }
/** Gets a result expression of this `switch` or conditional expression. */
Expr getAResultExpr() {
result = this.(ConditionalExpr).getTrueExpr() or
result = this.(ConditionalExpr).getFalseExpr() or
result = this.(SwitchExpr).getAResult()
}
}
/**
* A conditional expression of the form `a ? b : c`, where `a` is the condition,
* `b` is the expression that is evaluated if the condition evaluates to `true`,

View File

@@ -248,8 +248,7 @@ private predicate formatStringFragment(Expr fmt) {
e.(VarAccess).getVariable().getAnAssignedValue() = fmt or
e.(AddExpr).getLeftOperand() = fmt or
e.(AddExpr).getRightOperand() = fmt or
e.(ConditionalExpr).getTrueExpr() = fmt or
e.(ConditionalExpr).getFalseExpr() = fmt
e.(ChooseExpr).getAResultExpr() = fmt
)
}
@@ -293,9 +292,7 @@ private predicate formatStringValue(Expr e, string fmtvalue) {
fmtvalue = left + right
)
or
formatStringValue(e.(ConditionalExpr).getTrueExpr(), fmtvalue)
or
formatStringValue(e.(ConditionalExpr).getFalseExpr(), fmtvalue)
formatStringValue(e.(ChooseExpr).getAResultExpr(), fmtvalue)
or
exists(Method getprop, MethodAccess ma, string prop |
e = ma and

View File

@@ -213,7 +213,7 @@ private predicate hasPossibleUnknownValue(SsaVariable v) {
/**
* Gets a sub-expression of `e` whose value can flow to `e` through
* `ConditionalExpr`s. Parentheses are also removed.
* `ConditionalExpr`s.
*/
private Expr possibleValue(Expr e) {
result = possibleValue(e.(ConditionalExpr).getTrueExpr())

View File

@@ -10,8 +10,7 @@ private import RangeAnalysis
/** Gets an expression that might have the value `i`. */
private Expr exprWithIntValue(int i) {
result.(ConstantIntegerExpr).getIntValue() = i or
result.(ConditionalExpr).getTrueExpr() = exprWithIntValue(i) or
result.(ConditionalExpr).getFalseExpr() = exprWithIntValue(i)
result.(ChooseExpr).getAResultExpr() = exprWithIntValue(i)
}
/**

View File

@@ -45,8 +45,7 @@ private import semmle.code.java.frameworks.Assertions
/** Gets an expression that may be `null`. */
Expr nullExpr() {
result instanceof NullLiteral or
result.(ConditionalExpr).getTrueExpr() = nullExpr() or
result.(ConditionalExpr).getFalseExpr() = nullExpr() or
result.(ChooseExpr).getAResultExpr() = nullExpr() or
result.(AssignExpr).getSource() = nullExpr() or
result.(CastExpr).getExpr() = nullExpr()
}
@@ -81,9 +80,7 @@ private predicate unboxed(Expr e) {
or
exists(UnaryExpr un | un.getExpr() = e)
or
exists(ConditionalExpr cond | cond.getType() instanceof PrimitiveType |
cond.getTrueExpr() = e or cond.getFalseExpr() = e
)
exists(ChooseExpr cond | cond.getType() instanceof PrimitiveType | cond.getAResultExpr() = e)
or
exists(ConditionNode cond | cond.getCondition() = e)
or

View File

@@ -552,9 +552,7 @@ private Sign exprSign(Expr e) {
result = s1.urshift(s2)
)
or
result = exprSign(e.(ConditionalExpr).getTrueExpr())
or
result = exprSign(e.(ConditionalExpr).getFalseExpr())
result = exprSign(e.(ChooseExpr).getAResultExpr())
or
result = exprSign(e.(CastExpr).getExpr())
)

View File

@@ -72,9 +72,7 @@ private predicate privateParamArg(Parameter p, Argument arg) {
* necessarily functionally determined by `n2`.
*/
private predicate joinStep0(TypeFlowNode n1, TypeFlowNode n2) {
n2.asExpr().(ConditionalExpr).getTrueExpr() = n1.asExpr()
or
n2.asExpr().(ConditionalExpr).getFalseExpr() = n1.asExpr()
n2.asExpr().(ChooseExpr).getAResultExpr() = n1.asExpr()
or
exists(Field f, Expr e |
f = n2.asField() and
@@ -226,9 +224,8 @@ private predicate upcastCand(TypeFlowNode n, RefType t, RefType t1, RefType t2)
or
exists(Parameter p | privateParamArg(p, n.asExpr()) and t2 = p.getType().getErasure())
or
exists(ConditionalExpr cond |
cond.getTrueExpr() = n.asExpr() or cond.getFalseExpr() = n.asExpr()
|
exists(ChooseExpr cond |
cond.getAResultExpr() = n.asExpr() and
t2 = cond.getType().getErasure()
)
)

View File

@@ -397,9 +397,7 @@ predicate simpleLocalFlowStep(Node node1, Node node2) {
or
node2.asExpr().(CastExpr).getExpr() = node1.asExpr()
or
node2.asExpr().(ConditionalExpr).getTrueExpr() = node1.asExpr()
or
node2.asExpr().(ConditionalExpr).getFalseExpr() = node1.asExpr()
node2.asExpr().(ChooseExpr).getAResultExpr() = node1.asExpr()
or
node2.asExpr().(AssignExpr).getSource() = node1.asExpr()
}

View File

@@ -202,9 +202,7 @@ private predicate flowStep(RelevantNode n1, RelevantNode n2) {
or
n2.asExpr().(CastExpr).getExpr() = n1.asExpr()
or
n2.asExpr().(ConditionalExpr).getTrueExpr() = n1.asExpr()
or
n2.asExpr().(ConditionalExpr).getFalseExpr() = n1.asExpr()
n2.asExpr().(ChooseExpr).getAResultExpr() = n1.asExpr()
or
n2.asExpr().(AssignExpr).getSource() = n1.asExpr()
or

View File

@@ -100,9 +100,7 @@ private predicate step(Node n1, Node n2) {
or
n2.asExpr().(CastExpr).getExpr() = n1.asExpr()
or
n2.asExpr().(ConditionalExpr).getTrueExpr() = n1.asExpr()
or
n2.asExpr().(ConditionalExpr).getFalseExpr() = n1.asExpr()
n2.asExpr().(ChooseExpr).getAResultExpr() = n1.asExpr()
or
n2.asExpr().(AssignExpr).getSource() = n1.asExpr()
or