[PATCH] D28905: [analyzer] Consider function call arguments while building CallGraph
IvanSidorenko created this revision. Function call can appear in the arguments of another function call. This patch adds support for such cases. https://reviews.llvm.org/D28905 Files: lib/Analysis/CallGraph.cpp test/Analysis/debug-CallGraph.c Index: test/Analysis/debug-CallGraph.c === --- test/Analysis/debug-CallGraph.c +++ test/Analysis/debug-CallGraph.c @@ -1,5 +1,17 @@ // RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCallGraph %s -fblocks 2>&1 | FileCheck %s +int get5() { + return 5; +} + +int add(int val1, int val2) { + return val1 + val2; +} + +int test_add() { + return add(10, get5()); +} + static void mmm(int y) { if (y != 0) y++; @@ -32,7 +44,7 @@ void fff() { eee(); } // CHECK:--- Call graph Dump --- -// CHECK-NEXT: {{Function: < root > calls: mmm foo aaa < > bbb ccc ddd eee fff $}} +// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ccc ddd eee fff $}} // CHECK-NEXT: {{Function: fff calls: eee $}} // CHECK-NEXT: {{Function: eee calls: $}} // CHECK-NEXT: {{Function: ddd calls: ccc $}} @@ -42,3 +54,6 @@ // CHECK-NEXT: {{Function: aaa calls: foo $}} // CHECK-NEXT: {{Function: foo calls: mmm $}} // CHECK-NEXT: {{Function: mmm calls: $}} +// CHECK-NEXT: {{Function: test_add calls: add get5 $}} +// CHECK-NEXT: {{Function: add calls: $}} +// CHECK-NEXT: {{Function: get5 calls: $}} Index: lib/Analysis/CallGraph.cpp === --- lib/Analysis/CallGraph.cpp +++ lib/Analysis/CallGraph.cpp @@ -62,6 +62,7 @@ void VisitCallExpr(CallExpr *CE) { if (Decl *D = getDeclFromCall(CE)) addCalledDecl(D); +VisitChildren(CE); } // Adds may-call edges for the ObjC message sends. Index: test/Analysis/debug-CallGraph.c === --- test/Analysis/debug-CallGraph.c +++ test/Analysis/debug-CallGraph.c @@ -1,5 +1,17 @@ // RUN: %clang_cc1 -analyze -analyzer-checker=debug.DumpCallGraph %s -fblocks 2>&1 | FileCheck %s +int get5() { + return 5; +} + +int add(int val1, int val2) { + return val1 + val2; +} + +int test_add() { + return add(10, get5()); +} + static void mmm(int y) { if (y != 0) y++; @@ -32,7 +44,7 @@ void fff() { eee(); } // CHECK:--- Call graph Dump --- -// CHECK-NEXT: {{Function: < root > calls: mmm foo aaa < > bbb ccc ddd eee fff $}} +// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ccc ddd eee fff $}} // CHECK-NEXT: {{Function: fff calls: eee $}} // CHECK-NEXT: {{Function: eee calls: $}} // CHECK-NEXT: {{Function: ddd calls: ccc $}} @@ -42,3 +54,6 @@ // CHECK-NEXT: {{Function: aaa calls: foo $}} // CHECK-NEXT: {{Function: foo calls: mmm $}} // CHECK-NEXT: {{Function: mmm calls: $}} +// CHECK-NEXT: {{Function: test_add calls: add get5 $}} +// CHECK-NEXT: {{Function: add calls: $}} +// CHECK-NEXT: {{Function: get5 calls: $}} Index: lib/Analysis/CallGraph.cpp === --- lib/Analysis/CallGraph.cpp +++ lib/Analysis/CallGraph.cpp @@ -62,6 +62,7 @@ void VisitCallExpr(CallExpr *CE) { if (Decl *D = getDeclFromCall(CE)) addCalledDecl(D); +VisitChildren(CE); } // Adds may-call edges for the ObjC message sends. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
[PATCH] D29643: [analyzer] Do not duplicate call graph nodes for function that has definition and forward declaration.
IvanSidorenko created this revision. Fix in call graph construction: don't build call graph node for callee function twice for functions with forward declarations. Maybe the same fix should be done and for VisitObjCMethodDecl. Unfortunately, I have not enough expertise in ObjC, so I did not touch this code. Test case: void do_nothing() {} void test_single_call(); void test_single_call() { do_nothing(); } Output for the test case WITHOUT patch: Function: test_single_call calls: **do_nothing do_nothing** Function: do_nothing calls: Output for the test case WITH patch: Function: test_single_call calls: **do_nothing** Function: do_nothing calls: https://reviews.llvm.org/D29643 Files: include/clang/Analysis/CallGraph.h test/Analysis/debug-CallGraph.c Index: test/Analysis/debug-CallGraph.c === --- test/Analysis/debug-CallGraph.c +++ test/Analysis/debug-CallGraph.c @@ -43,8 +43,18 @@ void eee() {} void fff() { eee(); } +// This test case tests that forward declaration for the top-level function +// does not affect call graph construction. +void do_nothing() {} +void test_single_call(); +void test_single_call() { + do_nothing(); +} + // CHECK:--- Call graph Dump --- -// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ccc ddd eee fff $}} +// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ddd ccc eee fff do_nothing test_single_call $}} +// CHECK-NEXT: {{Function: test_single_call calls: do_nothing $}} +// CHECK-NEXT: {{Function: do_nothing calls: $}} // CHECK-NEXT: {{Function: fff calls: eee $}} // CHECK-NEXT: {{Function: eee calls: $}} // CHECK-NEXT: {{Function: ddd calls: ccc $}} Index: include/clang/Analysis/CallGraph.h === --- include/clang/Analysis/CallGraph.h +++ include/clang/Analysis/CallGraph.h @@ -98,7 +98,7 @@ bool VisitFunctionDecl(FunctionDecl *FD) { // We skip function template definitions, as their semantics is // only determined when they are instantiated. -if (includeInGraph(FD)) { +if (includeInGraph(FD) && FD->isThisDeclarationADefinition()) { // Add all blocks declared inside this function to the graph. addNodesForBlocks(FD); // If this function has external linkage, anything could call it. Index: test/Analysis/debug-CallGraph.c === --- test/Analysis/debug-CallGraph.c +++ test/Analysis/debug-CallGraph.c @@ -43,8 +43,18 @@ void eee() {} void fff() { eee(); } +// This test case tests that forward declaration for the top-level function +// does not affect call graph construction. +void do_nothing() {} +void test_single_call(); +void test_single_call() { + do_nothing(); +} + // CHECK:--- Call graph Dump --- -// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ccc ddd eee fff $}} +// CHECK-NEXT: {{Function: < root > calls: get5 add test_add mmm foo aaa < > bbb ddd ccc eee fff do_nothing test_single_call $}} +// CHECK-NEXT: {{Function: test_single_call calls: do_nothing $}} +// CHECK-NEXT: {{Function: do_nothing calls: $}} // CHECK-NEXT: {{Function: fff calls: eee $}} // CHECK-NEXT: {{Function: eee calls: $}} // CHECK-NEXT: {{Function: ddd calls: ccc $}} Index: include/clang/Analysis/CallGraph.h === --- include/clang/Analysis/CallGraph.h +++ include/clang/Analysis/CallGraph.h @@ -98,7 +98,7 @@ bool VisitFunctionDecl(FunctionDecl *FD) { // We skip function template definitions, as their semantics is // only determined when they are instantiated. -if (includeInGraph(FD)) { +if (includeInGraph(FD) && FD->isThisDeclarationADefinition()) { // Add all blocks declared inside this function to the graph. addNodesForBlocks(FD); // If this function has external linkage, anything could call it. ___ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits