|
13 | 13 | import csharp |
14 | 14 | import semmle.code.csharp.commons.StructuralComparison |
15 | 15 |
|
16 | | -class StructuralComparisonConfig extends StructuralComparisonConfiguration { |
17 | | - StructuralComparisonConfig() { this = "UselessIsBeforeAs" } |
18 | | - |
19 | | - override predicate candidate(ControlFlowElement x, ControlFlowElement y) { |
20 | | - exists(IfStmt is, AsExpr ae, IsExpr ie, TypeAccessPatternExpr tape | |
21 | | - ie = is.getCondition().getAChild*() and |
22 | | - tape = ie.getPattern() and |
23 | | - ae.getTargetType() = tape.getTarget() and |
24 | | - x = ie.getExpr() and |
25 | | - y = ae.getExpr() |
26 | | - | |
27 | | - ae = is.getThen().getAChild*() |
28 | | - or |
29 | | - ae = is.getElse().getAChild*() |
30 | | - ) |
31 | | - } |
| 16 | +private predicate candidate(AsExpr ae, IsExpr ie) { |
| 17 | + exists(IfStmt is, TypeAccessPatternExpr tape | |
| 18 | + ie = is.getCondition().getAChild*() and |
| 19 | + tape = ie.getPattern() and |
| 20 | + ae.getTargetType() = tape.getTarget() |
| 21 | + | |
| 22 | + ae = is.getThen().getAChild*() |
| 23 | + or |
| 24 | + ae = is.getElse().getAChild*() |
| 25 | + ) |
| 26 | +} |
32 | 27 |
|
33 | | - predicate uselessIsBeforeAs(AsExpr ae, IsExpr ie) { |
34 | | - exists(Expr x, Expr y | |
35 | | - same(x, y) and |
36 | | - ie.getExpr() = x and |
37 | | - ae.getExpr() = y |
38 | | - ) |
39 | | - } |
| 28 | +private predicate uselessIsBeforeAs(AsExpr ae, IsExpr ie) { |
| 29 | + candidate(ae, ie) and |
| 30 | + sameGvn(ie.getExpr(), ae.getExpr()) |
40 | 31 | } |
41 | 32 |
|
42 | 33 | from AsExpr ae, IsExpr ie |
43 | 34 | where |
44 | | - exists(StructuralComparisonConfig c | c.uselessIsBeforeAs(ae, ie)) and |
| 35 | + uselessIsBeforeAs(ae, ie) and |
45 | 36 | not exists(MethodCall mc | ae = mc.getAnArgument().getAChildExpr*()) |
46 | 37 | select ae, |
47 | 38 | "This 'as' expression performs a type test - it should be directly compared against null, rendering the 'is' $@ potentially redundant.", |
|
0 commit comments