En soi, l'appel-graphique est juste cela; il n'y a pas de "mauvais" graphiques d'appel (sauf si vous avez une vérification de style interdisant la récursivité). Le vrai problème est que pour comprendre comment le code à un point du programme peut être problématique, vous devez généralement comprendre la forme du monde (quelles sont les structures de données, quelles valeurs elles peuvent contenir, quelles relations elles peuvent avoir). avoir) au moment où ce point de code est actif. Le graphique d'appel montre comment l'exécution peut atteindre le point d'intérêt du code, et tout le code le long de ce chemin du graphe d'appel définit le contexte d'exécution du code. Cela permet à l'analyseur statique de produire une analyse «contextuelle», ce qui donne des réponses beaucoup plus précises.
Cela conduit à un deuxième problème: comment obtenir un graphique d'appel précis? Si vous avez un appel direct de B à partir de A, il est facile d'écrire «A appelle B» et de sentir que c'est un fait précis. Mais si A fait un appel à travers un pointeur indirect (pouvez-vous dire envoi de méthode virtuelle?) Tout à coup il n'est pas si clair exactement qui appelle A; vous finissez par A-pourrait-appeler-B1, A-pourrait-appeler-B2, ... Lequel A appelle réellement dépend en fait du contexte dans lequel A s'exécute ... oups, vous avez besoin du graphique d'appel pour fabriquer le graphique d'appel. Le genre de bonnes nouvelles est que vous construisez le graphique d'appel en partant du bas: "Je sais que c'est certainement vrai, donc cela doit sûrement être vrai". Aux endroits où l'analyseur ne peut pas le comprendre, il fait généralement une supposition conservatrice: ("Tous ces appels pourraient être possibles, je ne peux pas les exclure"). Ce conservatisme est l'une des principales causes de la précision de votre analyseur statique.