diff options
author | Roman Lebedev <lebedev.ri@gmail.com> | 2020-02-20 14:06:40 +0300 |
---|---|---|
committer | Roman Lebedev <lebedev.ri@gmail.com> | 2020-02-20 14:17:30 +0300 |
commit | c8f9e526bc5319f2d0beed4012fbf17b11e15161 (patch) | |
tree | 834c0d0101798aa6c5230fc427f478d6aee7af23 | |
parent | f4fd7dbf85e278eff303514760bff4773a87e601 (diff) | |
download | llvm-c8f9e526bc5319f2d0beed4012fbf17b11e15161.zip llvm-c8f9e526bc5319f2d0beed4012fbf17b11e15161.tar.gz llvm-c8f9e526bc5319f2d0beed4012fbf17b11e15161.tar.bz2 |
[clang-tidy] misc-no-recursion: point to the function defs, not decls
Results in slightly better UX.
This actually was the initial intent, but it kinda got lost along the way.
-rw-r--r-- | clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp | 9 | ||||
-rw-r--r-- | clang-tools-extra/test/clang-tidy/checkers/misc-no-recursion.cpp | 52 | ||||
-rw-r--r-- | clang/include/clang/Analysis/CallGraph.h | 4 |
3 files changed, 34 insertions, 31 deletions
diff --git a/clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp b/clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp index cfbd654..d382501d 100644 --- a/clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp +++ b/clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp @@ -204,9 +204,8 @@ void NoRecursionCheck::handleSCC(ArrayRef<CallGraphNode *> SCC) { // First of all, call out every stongly connected function. for (CallGraphNode *N : SCC) { - Decl *D = N->getDecl(); - diag(D->getLocation(), "function %0 is within a recursive call chain") - << cast<NamedDecl>(D); + FunctionDecl *D = N->getDefinition(); + diag(D->getLocation(), "function %0 is within a recursive call chain") << D; } // Now, SCC only tells us about strongly connected function declarations in @@ -228,13 +227,13 @@ void NoRecursionCheck::handleSCC(ArrayRef<CallGraphNode *> SCC) { assert(CyclicCallStack.size() >= 2 && "Cycle requires at least 2 frames"); // Which function we decided to be the entry point that lead to the recursion? - Decl *CycleEntryFn = CyclicCallStack.front().Callee->getDecl(); + FunctionDecl *CycleEntryFn = CyclicCallStack.front().Callee->getDefinition(); // And now, for ease of understanding, let's print the call sequence that // forms the cycle in question. diag(CycleEntryFn->getLocation(), "example recursive call chain, starting from function %0", DiagnosticIDs::Note) - << cast<NamedDecl>(CycleEntryFn); + << CycleEntryFn; for (int CurFrame = 1, NumFrames = CyclicCallStack.size(); CurFrame != NumFrames; ++CurFrame) { CallGraphNode::CallRecord PrevNode = CyclicCallStack[CurFrame - 1]; diff --git a/clang-tools-extra/test/clang-tidy/checkers/misc-no-recursion.cpp b/clang-tools-extra/test/clang-tidy/checkers/misc-no-recursion.cpp index 0cfacfe..e323c8a 100644 --- a/clang-tools-extra/test/clang-tidy/checkers/misc-no-recursion.cpp +++ b/clang-tools-extra/test/clang-tidy/checkers/misc-no-recursion.cpp @@ -60,12 +60,12 @@ void indirect_recursion() { conditionally_executed(); } +// CHECK-NOTES: :[[@LINE-9]]:6: warning: function 'conditionally_executed' is within a recursive call chain [misc-no-recursion] +// CHECK-NOTES: :[[@LINE-6]]:6: note: example recursive call chain, starting from function 'indirect_recursion' +// CHECK-NOTES: :[[@LINE-5]]:5: note: Frame #1: function 'indirect_recursion' calls function 'conditionally_executed' here: +// CHECK-NOTES: :[[@LINE-10]]:5: note: Frame #2: function 'conditionally_executed' calls function 'indirect_recursion' here: +// CHECK-NOTES: :[[@LINE-11]]:5: note: ... which was the starting point of the recursive call chain; there may be other cycles // CHECK-NOTES: :[[@LINE-10]]:6: warning: function 'indirect_recursion' is within a recursive call chain [misc-no-recursion] -// CHECK-NOTES: :[[@LINE-10]]:6: warning: function 'conditionally_executed' is within a recursive call chain [misc-no-recursion] -// CHECK-NOTES: :[[@LINE-12]]:6: note: example recursive call chain, starting from function 'indirect_recursion' -// CHECK-NOTES: :[[@LINE-6]]:5: note: Frame #1: function 'indirect_recursion' calls function 'conditionally_executed' here: -// CHECK-NOTES: :[[@LINE-11]]:5: note: Frame #2: function 'conditionally_executed' calls function 'indirect_recursion' here: -// CHECK-NOTES: :[[@LINE-12]]:5: note: ... which was the starting point of the recursive call chain; there may be other cycles void taint(); void maybe_selfrecursion_with_two_backedges() { @@ -97,13 +97,13 @@ void indirect_recursion_with_alternatives() { conditionally_executed_choice_1(); } -// CHECK-NOTES: :[[@LINE-16]]:6: warning: function 'indirect_recursion_with_alternatives' is within a recursive call chain [misc-no-recursion] -// CHECK-NOTES: :[[@LINE-16]]:6: warning: function 'conditionally_executed_choice_0' is within a recursive call chain [misc-no-recursion] -// CHECK-NOTES: :[[@LINE-18]]:6: note: example recursive call chain, starting from function 'indirect_recursion_with_alternatives' -// CHECK-NOTES: :[[@LINE-8]]:5: note: Frame #1: function 'indirect_recursion_with_alternatives' calls function 'conditionally_executed_choice_0' here: -// CHECK-NOTES: :[[@LINE-17]]:5: note: Frame #2: function 'conditionally_executed_choice_0' calls function 'indirect_recursion_with_alternatives' here: -// CHECK-NOTES: :[[@LINE-18]]:5: note: ... which was the starting point of the recursive call chain; there may be other cycles -// CHECK-NOTES: :[[@LINE-17]]:6: warning: function 'conditionally_executed_choice_1' is within a recursive call chain [misc-no-recursion] +// CHECK-NOTES: :[[@LINE-15]]:6: warning: function 'conditionally_executed_choice_0' is within a recursive call chain [misc-no-recursion] +// CHECK-NOTES: :[[@LINE-8]]:6: note: example recursive call chain, starting from function 'indirect_recursion_with_alternatives' +// CHECK-NOTES: :[[@LINE-7]]:5: note: Frame #1: function 'indirect_recursion_with_alternatives' calls function 'conditionally_executed_choice_0' here: +// CHECK-NOTES: :[[@LINE-16]]:5: note: Frame #2: function 'conditionally_executed_choice_0' calls function 'indirect_recursion_with_alternatives' here: +// CHECK-NOTES: :[[@LINE-17]]:5: note: ... which was the starting point of the recursive call chain; there may be other cycles +// CHECK-NOTES: :[[@LINE-16]]:6: warning: function 'conditionally_executed_choice_1' is within a recursive call chain [misc-no-recursion] +// CHECK-NOTES: :[[@LINE-13]]:6: warning: function 'indirect_recursion_with_alternatives' is within a recursive call chain [misc-no-recursion] static void indirect_recursion_with_depth2(); static void conditionally_executed_depth1() { @@ -119,14 +119,14 @@ void indirect_recursion_with_depth2() { conditionally_executed_depth0(); } -// CHECK-NOTES: :[[@LINE-14]]:13: warning: function 'indirect_recursion_with_depth2' is within a recursive call chain [misc-no-recursion] -// CHECK-NOTES: :[[@LINE-14]]:13: warning: function 'conditionally_executed_depth1' is within a recursive call chain [misc-no-recursion] -// CHECK-NOTES: :[[@LINE-11]]:13: note: example recursive call chain, starting from function 'conditionally_executed_depth0' -// CHECK-NOTES: :[[@LINE-10]]:5: note: Frame #1: function 'conditionally_executed_depth0' calls function 'conditionally_executed_depth1' here: -// CHECK-NOTES: :[[@LINE-15]]:5: note: Frame #2: function 'conditionally_executed_depth1' calls function 'indirect_recursion_with_depth2' here: -// CHECK-NOTES: :[[@LINE-8]]:5: note: Frame #3: function 'indirect_recursion_with_depth2' calls function 'conditionally_executed_depth0' here: -// CHECK-NOTES: :[[@LINE-9]]:5: note: ... which was the starting point of the recursive call chain; there may be other cycles -// CHECK-NOTES: :[[@LINE-16]]:13: warning: function 'conditionally_executed_depth0' is within a recursive call chain [misc-no-recursion] +// CHECK-NOTES: :[[@LINE-13]]:13: warning: function 'conditionally_executed_depth1' is within a recursive call chain [misc-no-recursion] +// CHECK-NOTES: :[[@LINE-10]]:13: note: example recursive call chain, starting from function 'conditionally_executed_depth0' +// CHECK-NOTES: :[[@LINE-9]]:5: note: Frame #1: function 'conditionally_executed_depth0' calls function 'conditionally_executed_depth1' here: +// CHECK-NOTES: :[[@LINE-14]]:5: note: Frame #2: function 'conditionally_executed_depth1' calls function 'indirect_recursion_with_depth2' here: +// CHECK-NOTES: :[[@LINE-7]]:5: note: Frame #3: function 'indirect_recursion_with_depth2' calls function 'conditionally_executed_depth0' here: +// CHECK-NOTES: :[[@LINE-8]]:5: note: ... which was the starting point of the recursive call chain; there may be other cycles +// CHECK-NOTES: :[[@LINE-15]]:13: warning: function 'conditionally_executed_depth0' is within a recursive call chain [misc-no-recursion] +// CHECK-NOTES: :[[@LINE-12]]:6: warning: function 'indirect_recursion_with_depth2' is within a recursive call chain [misc-no-recursion] int boo(); void foo(int x = boo()) {} @@ -139,12 +139,12 @@ int boo() { return 0; } -// CHECK-NOTES: :[[@LINE-11]]:5: warning: function 'boo' is within a recursive call chain [misc-no-recursion] -// CHECK-NOTES: :[[@LINE-10]]:6: warning: function 'bar' is within a recursive call chain [misc-no-recursion] -// CHECK-NOTES: :[[@LINE-13]]:5: note: example recursive call chain, starting from function 'boo' -// CHECK-NOTES: :[[@LINE-7]]:3: note: Frame #1: function 'boo' calls function 'bar' here: -// CHECK-NOTES: :[[@LINE-14]]:18: note: Frame #2: function 'bar' calls function 'boo' here: -// CHECK-NOTES: :[[@LINE-15]]:18: note: ... which was the starting point of the recursive call chain; there may be other cycles +// CHECK-NOTES: :[[@LINE-9]]:6: warning: function 'bar' is within a recursive call chain [misc-no-recursion] +// CHECK-NOTES: :[[@LINE-6]]:5: note: example recursive call chain, starting from function 'boo' +// CHECK-NOTES: :[[@LINE-6]]:3: note: Frame #1: function 'boo' calls function 'bar' here: +// CHECK-NOTES: :[[@LINE-13]]:18: note: Frame #2: function 'bar' calls function 'boo' here: +// CHECK-NOTES: :[[@LINE-14]]:18: note: ... which was the starting point of the recursive call chain; there may be other cycles +// CHECK-NOTES: :[[@LINE-10]]:5: warning: function 'boo' is within a recursive call chain [misc-no-recursion] int recursion_through_function_ptr() { auto *ptr = &recursion_through_function_ptr; diff --git a/clang/include/clang/Analysis/CallGraph.h b/clang/include/clang/Analysis/CallGraph.h index 0e56d1c..0410503 100644 --- a/clang/include/clang/Analysis/CallGraph.h +++ b/clang/include/clang/Analysis/CallGraph.h @@ -189,6 +189,10 @@ public: Decl *getDecl() const { return FD; } + FunctionDecl *getDefinition() const { + return getDecl()->getAsFunction()->getDefinition(); + } + void print(raw_ostream &os) const; void dump() const; }; |