[PATCH] D11328: [clang-tidy] new "throw-by-value-catch-by-reference" check for clang-tidy
Aaron Ballman via cfe-commits
cfe-commits at lists.llvm.org
Wed Oct 7 12:05:16 PDT 2015
aaron.ballman added a comment.
This patch is looking much closer! Thank you for continuing to work on it.
I found several mechanical changes that need to be made, like style, comments, formatting, isa<> followed by cast<>, etc. There is one logic issue regarding materialized temporaries that I think still needs to be addressed, but otherwise, this patch is getting close!
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:46
@@ +45,3 @@
+
+bool ThrowByValueCatchByReferenceCheck::isFunctionParameter(
+ const DeclRefExpr *declRefExpr) {
----------------
Judging by the function name, I think the code should actually be:
```
return isa<ParmVarDecl>(declRefExpr->getDecl());
```
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:60
@@ +59,3 @@
+ return false;
+ auto *varDecl = cast<VarDecl>(valueDecl);
+ return varDecl->isExceptionVariable();
----------------
Instead of isa<> followed by cast<>, the more idiomatic approach is:
```
if (const auto *VD = dyn_cast<VarDecl>(declRefExpr->getDecl()))
return VD->isExceptionVariable();
```
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:66
@@ +65,3 @@
+ const DeclRefExpr *declRefExpr)
+{
+ return isFunctionParameter(declRefExpr) || isCatchVariable(declRefExpr);
----------------
Should run clang-format over this; the brace should go with the closing paren.
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:78
@@ +77,3 @@
+ auto qualType = subExpr->getType();
+ auto *type = qualType.getTypePtr();
+ if (type->isPointerType()) {
----------------
No need to call getTypePtr(); QualType objects are thin wrappers around a Type *. So you can do qualType->isPointerType(), for instance.
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:86
@@ +85,3 @@
+ return;
+ //do not diagnose on catch variables
+ if (isa<DeclRefExpr>(inner)) {
----------------
Space between the comment and the start of the sentence; also, comments should be full sentences (with capitalization and punctuation). Applies here and elsewhere in the patch.
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:88
@@ +87,3 @@
+ if (isa<DeclRefExpr>(inner)) {
+ auto *declRef = cast<DeclRefExpr>(inner);
+ if (isCatchVariable(declRef))
----------------
Please use dyn_cast<> instead of isa<> followed by cast<>. Applies here and elsewhere in the patch.
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:93
@@ +92,3 @@
+ diag(subExpr->getLocStart(), "throw expression throws a pointer; it should "
+ "throw a non pointer value instead");
+ }
----------------
non-pointer, please
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:111
@@ +110,3 @@
+ auto *currentSubExpr = subExpr->IgnoreImpCasts();
+ const DeclRefExpr *variableReference;
+ if (isa<DeclRefExpr>(currentSubExpr))
----------------
This should be:
```
if (const auto *variableReference = dyn_cast<DeclRefExpr>(currentSubExpr)) {
} else if (const auto *constructorCall = dyn_cast<CXXConstructExpr>(currentSubExpr)) {
}
```
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:129
@@ +128,3 @@
+ // if it's a copy constructor it could copy from a lvalue
+ else if (constructorCall &&
+ constructorCall->getConstructor()->isCopyOrMoveConstructor()) {
----------------
I think that what we need to model here is: constructExpr(hasDescendant(materializeTemporaryExpr())) and expr(hasType(hasCanonicalType(builtinType())))
If the throw expression materializes a temporary, or it throws a builtin type, we are good. (Note, the checking for function parameter or catch variable is already done properly.)
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:156
@@ +155,3 @@
+ return;
+ auto *type = caughtType.getTypePtr();
+ auto *varDecl = catchStmt->getExceptionDecl();
----------------
No need to call getTypePtr().
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:159
@@ +158,3 @@
+ if (type->isPointerType()) {
+ auto canonical = type->getCanonicalTypeInternal().getTypePtr();
+ // check if pointed-to-type is char, wchar_t, char16_t, char32_t
----------------
Same here.
Also, please do not use getCanonicalTypeInternal(), you should use getCanonicalType() instead.
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:162
@@ +161,3 @@
+ auto *pointeeType =
+ cast<PointerType>(canonical)->getPointeeType().getTypePtr();
+ if (pointeeType->isAnyCharacterType() == false) {
----------------
A cleaner way to do this would be:
```
if (const auto *PT = getCanonicalType(caughtType)->getAs<PointerType>()) {
if (!PT->getPointeeType()->isAnyCharacterType())
diag(...);
}
This also corrects direct comparison against a Boolean on the next line.
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.h:43
@@ +42,3 @@
+ bool isFunctionOrCatchVar(const DeclRefExpr *declRefExpr);
+ const bool checkAnonymousTemporaries;
+};
----------------
Should be Check instead of check per style guidelines.
http://reviews.llvm.org/D11328
More information about the cfe-commits
mailing list