Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 50a905d

Browse files
authored
Merge pull request #459 from aschackmull/java/inherit-fix
Java: Fix inheritance relation for co-/contra-variant subtypes.
2 parents 77ca0cf + fe8dfee commit 50a905d

3 files changed

Lines changed: 31 additions & 36 deletions

File tree

java/ql/src/semmle/code/java/Type.qll

Lines changed: 18 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,7 @@ class RefType extends Type, Annotatable, Modifiable, @reftype {
420420
* Holds if this type declares or inherits method `m`, which is declared
421421
* in `declaringType`.
422422
*/
423-
predicate hasMethod(Method m, RefType declaringType) { hasMethod(m, declaringType, false) }
423+
predicate hasMethod(Method m, RefType declaringType) { this.hasMethod(m, declaringType, false) }
424424

425425
/**
426426
* Holds if this type declares or inherits method `m`, which is declared
@@ -430,29 +430,13 @@ class RefType extends Type, Annotatable, Modifiable, @reftype {
430430
*/
431431
cached
432432
predicate hasMethod(Method m, RefType declaringType, boolean hidden) {
433-
hasNonInterfaceMethod(m, declaringType, hidden)
433+
this.hasNonInterfaceMethod(m, declaringType, hidden)
434434
or
435-
hasInterfaceMethod(m, declaringType) and hidden = false
436-
}
437-
438-
private predicate noMethodExtraction() {
439-
not methods(_, _, _, _, this, _) and
440-
exists(Method m | methods(m, _, _, _, getSourceDeclaration(), _) and m.isInheritable())
441-
}
442-
443-
private predicate canInheritFromSupertype(RefType sup) {
444-
sup = getASupertype() and
445-
(noMethodExtraction() implies supertypeSrcDecl(sup, getSourceDeclaration()))
446-
}
447-
448-
pragma[nomagic]
449-
private predicate supertypeSrcDecl(RefType sup, RefType srcDecl) {
450-
sup = getASupertype() and
451-
srcDecl = sup.getSourceDeclaration()
435+
this.hasInterfaceMethod(m, declaringType) and hidden = false
452436
}
453437

454438
private predicate hasNonInterfaceMethod(Method m, RefType declaringType, boolean hidden) {
455-
m = getAMethod() and
439+
m = this.getAMethod() and
456440
this = declaringType and
457441
not declaringType instanceof Interface and
458442
hidden = false
@@ -464,7 +448,7 @@ class RefType extends Type, Annotatable, Modifiable, @reftype {
464448
else h1 = false
465449
) and
466450
(not sup instanceof Interface or this instanceof Interface) and
467-
canInheritFromSupertype(sup) and
451+
this.extendsOrImplements(sup) and
468452
sup.hasNonInterfaceMethod(m, declaringType, h2) and
469453
hidden = h1.booleanOr(h2) and
470454
exists(string signature |
@@ -477,30 +461,30 @@ class RefType extends Type, Annotatable, Modifiable, @reftype {
477461
private predicate cannotInheritInterfaceMethod(string signature) {
478462
methods(_, _, signature, _, this, _)
479463
or
480-
exists(Method m | hasNonInterfaceMethod(m, _, false) and methods(m, _, signature, _, _, _))
464+
exists(Method m | this.hasNonInterfaceMethod(m, _, false) and methods(m, _, signature, _, _, _))
481465
}
482466

483467
private predicate interfaceMethodCandidateWithSignature(
484468
Method m, string signature, RefType declaringType
485469
) {
486-
m = getAMethod() and
470+
m = this.getAMethod() and
487471
this = declaringType and
488472
declaringType instanceof Interface and
489473
methods(m, _, signature, _, _, _)
490474
or
491475
exists(RefType sup |
492476
sup.interfaceMethodCandidateWithSignature(m, signature, declaringType) and
493-
not cannotInheritInterfaceMethod(signature) and
494-
canInheritFromSupertype(sup) and
477+
not this.cannotInheritInterfaceMethod(signature) and
478+
this.extendsOrImplements(sup) and
495479
m.isInheritable()
496480
)
497481
}
498482

499483
pragma[nomagic]
500484
private predicate overrideEquivalentInterfaceMethodCandidates(Method m1, Method m2) {
501485
exists(string signature |
502-
interfaceMethodCandidateWithSignature(m1, signature, _) and
503-
interfaceMethodCandidateWithSignature(m2, signature, _) and
486+
this.interfaceMethodCandidateWithSignature(m1, signature, _) and
487+
this.interfaceMethodCandidateWithSignature(m2, signature, _) and
504488
m1 != m2 and
505489
m2.overrides(_) and
506490
any(Method m).overrides(m1)
@@ -510,27 +494,27 @@ class RefType extends Type, Annotatable, Modifiable, @reftype {
510494
pragma[noinline]
511495
private predicate overriddenInterfaceMethodCandidate(Method m) {
512496
exists(Method m2 |
513-
overrideEquivalentInterfaceMethodCandidates(m, m2) and
497+
this.overrideEquivalentInterfaceMethodCandidates(m, m2) and
514498
m2.overrides(m)
515499
)
516500
}
517501

518502
private predicate hasInterfaceMethod(Method m, RefType declaringType) {
519-
interfaceMethodCandidateWithSignature(m, _, declaringType) and
520-
not overriddenInterfaceMethodCandidate(m)
503+
this.interfaceMethodCandidateWithSignature(m, _, declaringType) and
504+
not this.overriddenInterfaceMethodCandidate(m)
521505
}
522506

523507
/** Holds if this type declares or inherits the specified member. */
524508
predicate inherits(Member m) {
525509
exists(Field f | f = m |
526-
f = getAField()
510+
f = this.getAField()
527511
or
528-
not f.isPrivate() and not declaresField(f.getName()) and getASupertype().inherits(f)
512+
not f.isPrivate() and not this.declaresField(f.getName()) and this.getASupertype().inherits(f)
529513
or
530-
getSourceDeclaration().inherits(f)
514+
this.getSourceDeclaration().inherits(f)
531515
)
532516
or
533-
hasMethod(m.(Method), _)
517+
this.hasMethod(m.(Method), _)
534518
}
535519

536520
/** Holds if this is a top-level type, which is not nested inside any other types. */
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
| NamingTest.java:4:17:4:22 | equals | Method NamingTest.equals(..) could be confused with overloaded method $@, since dispatch depends on static types. | NamingTest.java:3:17:3:22 | equals | equals |
1+
| NamingTest.java:7:17:7:22 | equals | Method NamingTest.equals(..) could be confused with overloaded method $@, since dispatch depends on static types. | NamingTest.java:6:17:6:22 | equals | equals |
Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,19 @@
1+
import java.util.*;
2+
import java.util.function.*;
3+
import java.util.stream.*;
14

25
public class NamingTest {
36
public boolean equals(Object other) { return false; }
47
public boolean equals(NamingTest other) { return true; }
5-
8+
69
public void visit(Object node) {}
710
public void visit(NamingTest t) {}
11+
12+
public class Elem<T> {}
13+
14+
public Object get(List<Elem<String>> lll) {
15+
Predicate<?> p = null;
16+
p.test(null);
17+
return lll.stream().map(l -> l).filter(Objects::nonNull).collect(Collectors.toList());
18+
}
819
}

0 commit comments

Comments
 (0)