Skip to content

Commit 4bdf545

Browse files
authored
Add note for base class to bugprone-throw-keyword-missing (#160751)
It might not always be clear which base the check found that has "exception" in its name. So we add a note to point to that class. Ideally we'd point to the `CXXBaseSpecifier`, but it seems we can't bind to that.
1 parent 4ff986a commit 4bdf545

File tree

3 files changed

+14
-4
lines changed

3 files changed

+14
-4
lines changed

clang-tools-extra/clang-tidy/bugprone/ThrowKeywordMissingCheck.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@ void ThrowKeywordMissingCheck::registerMatchers(MatchFinder *Finder) {
2020
hasType(cxxRecordDecl(anyOf(
2121
matchesName("[Ee]xception|EXCEPTION"),
2222
hasAnyBase(hasType(hasCanonicalType(recordType(hasDeclaration(
23-
cxxRecordDecl(matchesName("[Ee]xception|EXCEPTION")))))))))),
23+
cxxRecordDecl(matchesName("[Ee]xception|EXCEPTION"))
24+
.bind("base"))))))))),
2425
unless(anyOf(
2526
hasAncestor(
2627
stmt(anyOf(cxxThrowExpr(), callExpr(), returnStmt()))),
@@ -39,6 +40,11 @@ void ThrowKeywordMissingCheck::check(const MatchFinder::MatchResult &Result) {
3940
diag(TemporaryExpr->getBeginLoc(), "suspicious exception object created but "
4041
"not thrown; did you mean 'throw %0'?")
4142
<< TemporaryExpr->getType().getBaseTypeIdentifier()->getName();
43+
44+
if (const auto *BaseDecl = Result.Nodes.getNodeAs<Decl>("base"))
45+
diag(BaseDecl->getLocation(),
46+
"object type inherits from base class declared here",
47+
DiagnosticIDs::Note);
4248
}
4349

4450
} // namespace clang::tidy::bugprone

clang-tools-extra/docs/ReleaseNotes.rst

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,8 @@ Changes in existing checks
272272

273273
- Improved :doc:`bugprone-throw-keyword-missing
274274
<clang-tidy/checks/bugprone/throw-keyword-missing>` check by only considering
275-
the canonical types of base classes as written.
275+
the canonical types of base classes as written and adding a note on the base
276+
class that triggered the warning.
276277

277278
- Improved :doc:`bugprone-unchecked-optional-access
278279
<clang-tidy/checks/bugprone/unchecked-optional-access>` check by supporting

clang-tools-extra/test/clang-tidy/checkers/bugprone/throw-keyword-missing.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ typedef basic_string<char> string;
2020
typedef basic_string<wchar_t> wstring;
2121

2222
// std::exception and std::runtime_error declaration.
23+
// CHECK-MESSAGES-DAG: [[#EXCEPTION_LINE:@LINE + 1]]:8
2324
struct exception {
2425
exception();
2526
exception(const exception &other);
@@ -50,12 +51,13 @@ struct RegularException {
5051

5152
void stdExceptionNotTrownTest(int i) {
5253
if (i < 0)
53-
// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [bugprone-throw-keyword-missing]
54+
// CHECK-MESSAGES-DAG: :[[@LINE+1]]:5: warning: suspicious exception object created but not thrown; did you mean 'throw {{.*}}'? [bugprone-throw-keyword-missing]
5455
std::exception();
5556

5657
if (i > 0)
57-
// CHECK-MESSAGES: :[[@LINE+1]]:5: warning: suspicious exception
58+
// CHECK-MESSAGES-DAG: :[[@LINE+1]]:5: warning: suspicious exception
5859
std::runtime_error("Unexpected argument");
60+
// CHECK-MESSAGES: note: object type inherits from base class declared here
5961
}
6062

6163
void stdExceptionThrownTest(int i) {
@@ -181,6 +183,7 @@ class RegularError : public ERROR_BASE {};
181183
void typedefTest() {
182184
// CHECK-MESSAGES: :[[@LINE+1]]:3: warning: suspicious exception
183185
RegularError();
186+
// CHECK-MESSAGES: :[[#EXCEPTION_LINE]]:8: note: object type inherits from base class declared here
184187
}
185188

186189
struct ExceptionRAII {

0 commit comments

Comments
 (0)