@@ -2,11 +2,59 @@ private import cpp
22private import DataFlowPrivate
33
44Function viableImpl ( MethodAccess ma ) {
5- result = ma . getTarget ( )
5+ result = viableCallable ( ma )
66}
77
8+ /**
9+ * Gets a function that might be called by `call`.
10+ */
811Function viableCallable ( Call call ) {
912 result = call .getTarget ( )
13+ or
14+ // If the target of the call does not have a body in the snapshot, it might
15+ // be because the target is just a header declaration, and the real target
16+ // will be determined at run time when the caller and callee are linked
17+ // together by the operating system's dynamic linker. In case a _unique_
18+ // function with the right signature is present in the database, we return
19+ // that as a potential callee.
20+ exists ( string qualifiedName , int nparams |
21+ callSignatureWithoutBody ( qualifiedName , nparams , call ) and
22+ functionSignatureWithBody ( qualifiedName , nparams , result ) and
23+ strictcount ( Function other | functionSignatureWithBody ( qualifiedName , nparams , other ) ) = 1
24+ )
25+ }
26+
27+ /**
28+ * Holds if `f` is a function with a body that has name `qualifiedName` and
29+ * `nparams` parameter count. See `functionSignature`.
30+ */
31+ private predicate functionSignatureWithBody ( string qualifiedName , int nparams , Function f ) {
32+ functionSignature ( f , qualifiedName , nparams ) and
33+ exists ( f .getBlock ( ) )
34+ }
35+
36+ /**
37+ * Holds if the target of `call` is a function _with no definition_ that has
38+ * name `qualifiedName` and `nparams` parameter count. See `functionSignature`.
39+ */
40+ pragma [ noinline]
41+ private predicate callSignatureWithoutBody ( string qualifiedName , int nparams , Call call ) {
42+ exists ( Function target |
43+ target = call .getTarget ( ) and
44+ not exists ( target .getBlock ( ) ) and
45+ functionSignature ( target , qualifiedName , nparams )
46+ )
47+ }
48+
49+ /**
50+ * Holds if `f` has name `qualifiedName` and `nparams` parameter count. This is
51+ * an approximation of its signature for the purpose of matching functions that
52+ * might be the same across link targets.
53+ */
54+ private predicate functionSignature ( Function f , string qualifiedName , int nparams ) {
55+ qualifiedName = f .getQualifiedName ( ) and
56+ nparams = f .getNumberOfParameters ( ) and
57+ not f .isStatic ( )
1058}
1159
1260/**
0 commit comments