|
13 | 13 | import csharp |
14 | 14 | import semmle.code.csharp.commons.StructuralComparison |
15 | 15 |
|
16 | | -class StructuralComparisonConfig extends StructuralComparisonConfiguration { |
17 | | - StructuralComparisonConfig() { this = "SelfAssignment" } |
18 | | - |
19 | | - override predicate candidate(ControlFlowElement x, ControlFlowElement y) { |
20 | | - exists(AssignExpr ae | |
21 | | - // Member initializers are never self-assignments, in particular |
22 | | - // not initializers such as `new C { F = F };` |
23 | | - not ae instanceof MemberInitializer and |
24 | | - // Enum field initializers are never self assignments. `enum E { A = 42 }` |
25 | | - not ae.getParent().(Field).getDeclaringType() instanceof Enum |
26 | | - | |
27 | | - ae.getLValue() = x and |
28 | | - ae.getRValue() = y |
29 | | - ) and |
30 | | - forall(Expr e | e = x.(Expr).getAChildExpr*() | |
31 | | - // Non-trivial property accesses may have side-effects, |
32 | | - // so these are not considered |
33 | | - e instanceof PropertyAccess implies e instanceof TrivialPropertyAccess |
34 | | - ) |
35 | | - } |
| 16 | +private predicate candidate(AssignExpr ae) { |
| 17 | + // Member initializers are never self-assignments, in particular |
| 18 | + // not initializers such as `new C { F = F };` |
| 19 | + not ae instanceof MemberInitializer and |
| 20 | + // Enum field initializers are never self assignments. `enum E { A = 42 }` |
| 21 | + not ae.getParent().(Field).getDeclaringType() instanceof Enum and |
| 22 | + forall(Expr e | e = ae.getLValue().getAChildExpr*() | |
| 23 | + // Non-trivial property accesses may have side-effects, |
| 24 | + // so these are not considered |
| 25 | + e instanceof PropertyAccess implies e instanceof TrivialPropertyAccess |
| 26 | + ) |
| 27 | +} |
36 | 28 |
|
37 | | - AssignExpr getSelfAssignExpr() { |
38 | | - exists(Expr x, Expr y | |
39 | | - same(x, y) and |
40 | | - result.getLValue() = x and |
41 | | - result.getRValue() = y |
42 | | - ) |
43 | | - } |
| 29 | +private predicate selfAssignExpr(AssignExpr ae) { |
| 30 | + candidate(ae) and |
| 31 | + sameGvn(ae.getLValue(), ae.getRValue()) |
44 | 32 | } |
45 | 33 |
|
46 | | -Declaration getDeclaration(Expr e) { |
| 34 | +private Declaration getDeclaration(Expr e) { |
47 | 35 | result = e.(VariableAccess).getTarget() |
48 | 36 | or |
49 | 37 | result = e.(MemberAccess).getTarget() |
50 | 38 | or |
51 | 39 | result = getDeclaration(e.(ArrayAccess).getQualifier()) |
52 | 40 | } |
53 | 41 |
|
54 | | -from StructuralComparisonConfig c, AssignExpr ae, Declaration target |
55 | | -where ae = c.getSelfAssignExpr() and target = getDeclaration(ae.getLValue()) |
| 42 | +from AssignExpr ae, Declaration target |
| 43 | +where selfAssignExpr(ae) and target = getDeclaration(ae.getLValue()) |
56 | 44 | select ae, "This assignment assigns $@ to itself.", target, target.getName() |
0 commit comments