forked from github/codeql
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathConstantExpAppearsNonConstant.ql
More file actions
67 lines (63 loc) · 2.22 KB
/
ConstantExpAppearsNonConstant.ql
File metadata and controls
67 lines (63 loc) · 2.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
/**
* @name Expression always evaluates to the same value
* @description An expression that always evaluates to the same value, but which has a non-constant subexpression, indicates a mistake.
* @kind problem
* @problem.severity warning
* @precision very-high
* @id java/evaluation-to-constant
* @tags quality
* reliability
* correctness
*/
import java
import semmle.code.java.frameworks.kotlin.Serialization
int eval(Expr e) { result = e.(CompileTimeConstantExpr).getIntValue() }
predicate isConstantExp(Expr e) {
// A literal is constant.
e instanceof Literal
or
e instanceof TypeAccess
or
e instanceof ArrayTypeAccess
or
e instanceof WildcardTypeAccess
or
// A binary expression is constant if both its operands are.
exists(BinaryExpr b | b = e |
isConstantExp(b.getLeftOperand()) and
isConstantExp(b.getRightOperand())
)
or
// A cast expression is constant if its expression is.
exists(CastingExpr c | c = e | isConstantExp(c.getExpr()))
or
// Multiplication by 0 is constant.
exists(MulExpr m | m = e | eval(m.getAnOperand()) = 0)
or
// Integer remainder by 1 is constant.
exists(RemExpr r | r = e |
r.getLeftOperand().getType() instanceof IntegralType and
eval(r.getRightOperand()) = 1
)
or
exists(AndBitwiseExpr a | a = e | eval(a.getAnOperand()) = 0)
or
exists(AndLogicalExpr a | a = e | a.getAnOperand().(BooleanLiteral).getBooleanValue() = false)
or
exists(OrLogicalExpr o | o = e | o.getAnOperand().(BooleanLiteral).getBooleanValue() = true)
}
from Expr e
where
isConstantExp(e) and
exists(Expr child | e.getAChildExpr() = child |
not isConstantExp(child) and
not child instanceof Annotation
) and
not e instanceof CompileTimeConstantExpr and
// Exclude explicit zero multiplication.
not e.(MulExpr).getAnOperand().(IntegerLiteral).getIntValue() = 0 and
// Exclude expressions that appear to be disabled deliberately (e.g. `false && ...`).
not e.(AndLogicalExpr).getAnOperand().(BooleanLiteral).getBooleanValue() = false and
// Exclude expressions that are in serialization constructors, which are auto-generated.
not e.getEnclosingCallable() instanceof SerializationConstructor
select e, "Expression always evaluates to the same value."