-
Notifications
You must be signed in to change notification settings - Fork 2k
Expand file tree
/
Copy pathRedundantExpression.ql
More file actions
105 lines (94 loc) · 2.84 KB
/
RedundantExpression.ql
File metadata and controls
105 lines (94 loc) · 2.84 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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
/**
* @name Identical operands
* @description Passing identical, or seemingly identical, operands to an
* operator such as subtraction or conjunction may indicate a typo;
* even if it is intentional, it makes the code hard to read.
* @kind problem
* @problem.severity warning
* @id js/redundant-operation
* @tags reliability
* correctness
* external/cwe/cwe-480
* external/cwe/cwe-561
* @precision very-high
*/
import Clones
/**
* A clone detector that finds redundant expressions.
*/
abstract class RedundantOperand extends StructurallyCompared {
RedundantOperand() {
exists (BinaryExpr parent | this = parent.getLeftOperand())
}
override Expr candidate() {
result = getParent().(BinaryExpr).getRightOperand()
}
/** Gets the expression to report when a pair of clones is found. */
Expr toReport() {
result = getParent()
}
}
/**
* A binary expression whose operator is idemnecant.
*
* An idemnecant operator is an operator that yields a trivial result when applied to
* identical operands (disregarding overflow and special floating point values).
*
* For instance, subtraction is idemnecant (since `e-e=0`), and so is division (since `e/e=1`).
*/
class IdemnecantExpr extends BinaryExpr {
IdemnecantExpr() {
this instanceof SubExpr or
this instanceof DivExpr or
this instanceof ModExpr or
this instanceof XOrExpr
}
}
/**
* A clone detector for idemnecant operators.
*/
class RedundantIdemnecantOperand extends RedundantOperand {
RedundantIdemnecantOperand() {
exists (IdemnecantExpr parent |
parent = getParent() and
// exclude trivial cases like `1-1`
not parent.getRightOperand().getUnderlyingValue() instanceof Literal
)
}
}
/**
* A clone detector for idempotent expressions.
*
* Note that `&` and `|` are not idempotent in JavaScript, since they coerce their
* arguments to integers. For example, `x&x` is a common idiom for converting `x` to an integer.
*/
class RedundantIdempotentOperand extends RedundantOperand {
RedundantIdempotentOperand() {
getParent() instanceof LogicalBinaryExpr
}
}
/**
* An expression of the form `(e + f)/2`.
*/
class AverageExpr extends DivExpr {
AverageExpr() {
getLeftOperand().getUnderlyingValue() instanceof AddExpr and
getRightOperand().getIntValue() = 2
}
}
/**
* A clone detector for redundant expressions of the form `(e + e)/2`.
*/
class RedundantAverageOperand extends RedundantOperand {
RedundantAverageOperand() {
exists (AverageExpr aver |
(AddExpr)getParent() = aver.getLeftOperand().getUnderlyingValue()
)
}
override AverageExpr toReport() {
getParent() = result.getLeftOperand().getUnderlyingValue()
}
}
from RedundantOperand e, Expr f
where e.same(f)
select e.toReport(), "Operands $@ and $@ are identical.", e, e.toString(), f, f.toString()