[cfe-dev] Missing edges in analysis call graph

Daniel DeFreez dcdefreez at ucdavis.edu
Tue Nov 18 09:08:52 PST 2014


Hi all,

I've been working with the static analyzer and I'm having issues with the
call graph that it produces. This is the same call graph that is output by
the debug.DumpCallGraph and debug.ViewCallGraph checkers. I'm fairly new to
clang, so I would like some feedback on this. Maybe I've missed the mark
entirely or there is a better way to fix it. Thanks in advance, the static
analyzer is awesome.

With clang version 3.6.0 (trunk 222230), running
-analyzer-checker=debug.DumpCallGraph for two equivalent pieces of code
produces different results:

First sample
------------------
void a() {}
void b() { a(); }

 --- Call graph Dump ---
  Function: < root > calls: a b
  Function: b calls: a
  Function: a calls:

Second sample
----------------------
void a();
void b() { a(); }
void a() {}

 --- Call graph Dump ---
  Function: < root > calls: b a
  Function: a calls:
  Function: b calls:

Shouldn't the call graph in the second code sample also have an edge from b
to a?

I think this happens because the check at /lib/Analysis/CallGraph.cpp:119
throws out Decls based on isThisDeclarationADefinition(). The comment says
that this is used to discard template definitions, but the check is too
broad.
When the b-a CallExpr is visited, DeclRefExpr points at the declaration of
the function not the definition, so it is not included in the graph.

*Feedback please*
I fixed it as below. The idea is to filter out template definitions in
addition to function definitions that have a previous declaration, but not
all declarations.

   if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+    // Skip definitions with previous declarations
+    if (FD->getPreviousDecl())
+      return false;
+
     // We skip function template definitions, as their semantics is
     // only determined when they are instantiated.
-    if (!FD->isThisDeclarationADefinition() ||
+    if (FD->getDescribedFunctionTemplate() ||
         FD->isDependentContext())
       return false;

Is this right?

Thanks,

Daniel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20141118/3e676155/attachment.html>


More information about the cfe-dev mailing list