Some cases in the Class Hierarchy Algorithm are not considered.
The program for inputting into the CHA is as follows:
package org.demo;
class A {
public void foo(){}
}
class B extends A {
}
class C extends B{
@Override
public void foo() {
super.foo();
}
}
The Call Graph result is <org.demo.C: void foo()> -> <org.demo.B: void foo()>
But the expected result should be <org.demo.C: void foo()> -> <org.demo.A: void foo()>
In class C, the foo method contains a call to the parent class's foo method. (super.foo(); is a specialinvoke)
However, it is clear that class B's foo method inherits from the parent class A.
let's examine the resolveCall method of the ClassHierarchyAnalysisAlgorithm class.
If the invocation statement is a JSpecialInvokeExpr, return the method signature of the current invocation expression which is the variable targetMethodSignature.
In the above case, if targetMethod is not null, resolveCall should return targetMethod.getSignature() for JSpecialInvokeExpr.
This is because when calling a method from the parent class, the callee method could be a method that was inherited (not overridden) from its parent class.
For the two other cases of JSpecialInvokeExpr, which are the invocation of constructor methods and private methods, this issue does not exist.
Additionally, static methods can also be inherited, so looking at the method signature alone cannot determine the class where the target method resides.
Therefore, it is recommended to make the following modifications:
What happened?
Some cases in the Class Hierarchy Algorithm are not considered. The program for inputting into the CHA is as follows:
The Call Graph result is
<org.demo.C: void foo()> -> <org.demo.B: void foo()>
But the expected result should be<org.demo.C: void foo()> -> <org.demo.A: void foo()>
In class C, the foo method contains a call to the parent class's foo method. (
super.foo();
is aspecialinvoke
) However, it is clear that class B's foo method inherits from the parent class A.let's examine the
resolveCall
method of theClassHierarchyAnalysisAlgorithm
class.If the invocation statement is a
JSpecialInvokeExpr
, return the method signature of the current invocation expression which is the variabletargetMethodSignature
. In the above case, iftargetMethod
is not null,resolveCall
should returntargetMethod.getSignature()
forJSpecialInvokeExpr
. This is because when calling a method from the parent class, the callee method could be a method that was inherited (not overridden) from its parent class. For the two other cases ofJSpecialInvokeExpr
, which are the invocation of constructor methods and private methods, this issue does not exist. Additionally, static methods can also be inherited, so looking at the method signature alone cannot determine the class where the target method resides.Therefore, it is recommended to make the following modifications:
Version
Latest develop branch
Relevant log output