[clang] c8f9e52 - [clang-tidy] misc-no-recursion: point to the function defs, not decls
Roman Lebedev via cfe-commits
cfe-commits at lists.llvm.org
Thu Feb 20 03:27:15 PST 2020
Author: Roman Lebedev
Date: 2020-02-20T14:17:30+03:00
New Revision: c8f9e526bc5319f2d0beed4012fbf17b11e15161
URL: https://github.com/llvm/llvm-project/commit/c8f9e526bc5319f2d0beed4012fbf17b11e15161
DIFF: https://github.com/llvm/llvm-project/commit/c8f9e526bc5319f2d0beed4012fbf17b11e15161.diff
LOG: [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.
Added:
Modified:
clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp
clang-tools-extra/test/clang-tidy/checkers/misc-no-recursion.cpp
clang/include/clang/Analysis/CallGraph.h
Removed:
################################################################################
diff --git a/clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp b/clang-tools-extra/clang-tidy/misc/NoRecursionCheck.cpp
index cfbd6543e086..d382501d191e 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 0cfacfe80cbe..e323c8a36a2b 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 0e56d1c00623..041050319239 100644
--- a/clang/include/clang/Analysis/CallGraph.h
+++ b/clang/include/clang/Analysis/CallGraph.h
@@ -189,6 +189,10 @@ class CallGraphNode {
Decl *getDecl() const { return FD; }
+ FunctionDecl *getDefinition() const {
+ return getDecl()->getAsFunction()->getDefinition();
+ }
+
void print(raw_ostream &os) const;
void dump() const;
};
More information about the cfe-commits
mailing list