r369321 - [CallGraph] Take into accound calls that aren't within any function bodies.

Artem Dergachev via cfe-commits cfe-commits at lists.llvm.org
Mon Aug 19 19:22:38 PDT 2019


Author: dergachev
Date: Mon Aug 19 19:22:37 2019
New Revision: 369321

URL: http://llvm.org/viewvc/llvm-project?rev=369321&view=rev
Log:
[CallGraph] Take into accound calls that aren't within any function bodies.

This patch improves Clang call graph analysis by adding in expressions
that are not found in regular function bodies, such as default arguments
or member initializers.

Patch by Joshua Cranmer!

Differential Revision: https://reviews.llvm.org/D65453

Added:
    cfe/trunk/test/Analysis/cxx-callgraph.cpp
Modified:
    cfe/trunk/include/clang/Analysis/CallGraph.h
    cfe/trunk/lib/Analysis/CallGraph.cpp
    cfe/trunk/test/Analysis/exploded-graph-rewriter/objects_under_construction.cpp

Modified: cfe/trunk/include/clang/Analysis/CallGraph.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Analysis/CallGraph.h?rev=369321&r1=369320&r2=369321&view=diff
==============================================================================
--- cfe/trunk/include/clang/Analysis/CallGraph.h (original)
+++ cfe/trunk/include/clang/Analysis/CallGraph.h Mon Aug 19 19:22:37 2019
@@ -131,6 +131,7 @@ public:
 
   bool shouldWalkTypesOfTypeLocs() const { return false; }
   bool shouldVisitTemplateInstantiations() const { return true; }
+  bool shouldVisitImplicitCode() const { return true; }
 
 private:
   /// Add the given declaration to the call graph.

Modified: cfe/trunk/lib/Analysis/CallGraph.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Analysis/CallGraph.cpp?rev=369321&r1=369320&r2=369321&view=diff
==============================================================================
--- cfe/trunk/lib/Analysis/CallGraph.cpp (original)
+++ cfe/trunk/lib/Analysis/CallGraph.cpp Mon Aug 19 19:22:37 2019
@@ -79,6 +79,34 @@ public:
     VisitChildren(CE);
   }
 
+  void VisitLambdaExpr(LambdaExpr *LE) {
+    if (CXXMethodDecl *MD = LE->getCallOperator())
+      G->VisitFunctionDecl(MD);
+  }
+
+  void VisitCXXNewExpr(CXXNewExpr *E) {
+    if (FunctionDecl *FD = E->getOperatorNew())
+      addCalledDecl(FD);
+    VisitChildren(E);
+  }
+
+  void VisitCXXConstructExpr(CXXConstructExpr *E) {
+    CXXConstructorDecl *Ctor = E->getConstructor();
+    if (FunctionDecl *Def = Ctor->getDefinition())
+      addCalledDecl(Def);
+    VisitChildren(E);
+  }
+
+  // Include the evaluation of the default argument.
+  void VisitCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
+    Visit(E->getExpr());
+  }
+
+  // Include the evaluation of the default initializers in a class.
+  void VisitCXXDefaultInitExpr(CXXDefaultInitExpr *E) {
+    Visit(E->getExpr());
+  }
+
   // Adds may-call edges for the ObjC message sends.
   void VisitObjCMessageExpr(ObjCMessageExpr *ME) {
     if (ObjCInterfaceDecl *IDecl = ME->getReceiverInterface()) {
@@ -143,13 +171,20 @@ bool CallGraph::includeInGraph(const Dec
 void CallGraph::addNodeForDecl(Decl* D, bool IsGlobal) {
   assert(D);
 
-  // Allocate a new node, mark it as root, and process it's calls.
+  // Allocate a new node, mark it as root, and process its calls.
   CallGraphNode *Node = getOrInsertNode(D);
 
   // Process all the calls by this function as well.
   CGBuilder builder(this, Node);
   if (Stmt *Body = D->getBody())
     builder.Visit(Body);
+
+  // Include C++ constructor member initializers.
+  if (auto constructor = dyn_cast<CXXConstructorDecl>(D)) {
+    for (CXXCtorInitializer *init : constructor->inits()) {
+      builder.Visit(init->getInit());
+    }
+  }
 }
 
 CallGraphNode *CallGraph::getNode(const Decl *F) const {

Added: cfe/trunk/test/Analysis/cxx-callgraph.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/cxx-callgraph.cpp?rev=369321&view=auto
==============================================================================
--- cfe/trunk/test/Analysis/cxx-callgraph.cpp (added)
+++ cfe/trunk/test/Analysis/cxx-callgraph.cpp Mon Aug 19 19:22:37 2019
@@ -0,0 +1,29 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=debug.DumpCallGraph %s 2>&1 | FileCheck %s
+
+static int aaa() {
+  return 0;
+}
+
+static int bbb(int param=aaa()) {
+  return 1;
+}
+
+int ddd();
+
+struct c {
+  c(int param=2) : val(bbb(param)) {}
+  int val;
+  int val2 = ddd();
+};
+
+int ddd() {
+  c c;
+  return bbb();
+}
+
+// CHECK:--- Call graph Dump ---
+// CHECK-NEXT: {{Function: < root > calls: aaa bbb c::c ddd}}
+// CHECK-NEXT: {{Function: c::c calls: bbb ddd $}}
+// CHECK-NEXT: {{Function: ddd calls: c::c bbb aaa $}}
+// CHECK-NEXT: {{Function: bbb calls: $}}
+// CHECK-NEXT: {{Function: aaa calls: $}}

Modified: cfe/trunk/test/Analysis/exploded-graph-rewriter/objects_under_construction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Analysis/exploded-graph-rewriter/objects_under_construction.cpp?rev=369321&r1=369320&r2=369321&view=diff
==============================================================================
--- cfe/trunk/test/Analysis/exploded-graph-rewriter/objects_under_construction.cpp (original)
+++ cfe/trunk/test/Analysis/exploded-graph-rewriter/objects_under_construction.cpp Mon Aug 19 19:22:37 2019
@@ -1,5 +1,6 @@
 // FIXME: Figure out how to use %clang_analyze_cc1 with our lit.local.cfg.
 // RUN: %clang_cc1 -analyze -triple x86_64-unknown-linux-gnu \
+// RUN:                     -analyze-function "test()" \
 // RUN:                     -analyzer-checker=core \
 // RUN:                     -analyzer-dump-egraph=%t.dot %s
 // RUN: %exploded_graph_rewriter %t.dot | FileCheck %s




More information about the cfe-commits mailing list