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

Skip to content

Commit 2d64fed

Browse files
committed
CPP: Speed up VirtualDispatch.qll's getAViableTarget.
1 parent c40c88e commit 2d64fed

1 file changed

Lines changed: 16 additions & 12 deletions

File tree

cpp/ql/src/semmle/code/cpp/dispatch/VirtualDispatch.qll

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,19 @@ module VirtualDispatch {
2828
not result.hasName("IUnknown")
2929
}
3030

31+
/**
32+
* Helper predicate for `getAViableTarget`, which computes the viable targets for
33+
* virtual calls based on the qualifier type.
34+
*/
35+
private Function getAViableVirtualCallTarget(Class qualifierType, MemberFunction staticTarget) {
36+
exists(Class qualifierSubType |
37+
result = getAPossibleImplementation(staticTarget) and
38+
qualifierType = qualifierSubType.getABaseClass*() and
39+
mayInherit(qualifierSubType, result) and
40+
not cannotInherit(qualifierSubType, result)
41+
)
42+
}
43+
3144
/**
3245
* Gets a viable target for the given function call.
3346
*
@@ -42,18 +55,9 @@ module VirtualDispatch {
4255
* If `c` is not a virtual call, the result will be `c.getTarget()`.
4356
*/
4457
Function getAViableTarget(Call c) {
45-
exists(Function staticTarget | staticTarget = c.getTarget() |
46-
if c.(FunctionCall).isVirtual() and staticTarget instanceof MemberFunction
47-
then
48-
exists(Class qualifierType, Class qualifierSubType |
49-
result = getAPossibleImplementation(staticTarget) and
50-
qualifierType = getCallQualifierType(c) and
51-
qualifierType = qualifierSubType.getABaseClass*() and
52-
mayInherit(qualifierSubType, result) and
53-
not cannotInherit(qualifierSubType, result)
54-
)
55-
else result = staticTarget
56-
)
58+
if c.(FunctionCall).isVirtual() and c.getTarget() instanceof MemberFunction
59+
then result = getAViableVirtualCallTarget(getCallQualifierType(c), c.getTarget())
60+
else result = c.getTarget()
5761
}
5862

5963
/** Holds if `f` is declared in `c` or a transitive base class of `c`. */

0 commit comments

Comments
 (0)