[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 14:44:43 PDT 2015
aaron.ballman added a comment.
On Wed, Oct 7, 2015 at 5:08 PM, Tobias Langner <randomcppprogrammer at gmail.com> wrote:
> Hi,
>
> I incorporated most of your changes. There are 2 open issues
Thank you for your work on this! There are a few minor nitpicks still, but is definitely moving forward nicely.
> - on one location I could not follow your advice, the compiler refused to compile the code. I chose a different approach and hope you like it.
> - the second thing is this MaterializeTemporary advice that you gave. I don’t fully understand it (possibly due to a lack of understanding the AST and a lack of documentation of the proposed methods). Could you please flesh out your idea and why you think it is necessary? Or at least give an example where the current code does not work correctly.
Consider code like:
struct S {};
S& g();
S h();
void f() {
throw g(); // Should diagnose, does not currently
throw h(); // Should not diagnose, does not currently
}
"throw g();" isn't throwing a temporary because it's throwing from an lvalue reference object (so the user may have a catch clause expecting the caught object to be the same lvalue reference as what g() returns, except that's not actually the case). If you instead check to see whether the throw expression requires a temporary to be materialized, you'll find that g() will diagnose, while h() still will not.
Does that help?
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:55
@@ +54,3 @@
+ auto *varDecl = dyn_cast<VarDecl>(valueDecl);
+ return varDecl ? varDecl->isExceptionVariable() : false;
+}
----------------
How about:
```
if (const auto *VD = dyn_cast<VarDecl>(declRefExpr->getDecl()))
return VD->isExceptionVariable();
return false;
```
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:72
@@ +71,3 @@
+ if (qualType->isPointerType()) {
+ // the code is throwing a pointer
+ // in case it is strng literal, it is safe and we return
----------------
Sentence capitalization and punctuation in the comment.
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:77
@@ +76,3 @@
+ return;
+ // if it's a variable from a catch statement, we return as well
+ auto *declRef = dyn_cast<DeclRefExpr>(inner);
----------------
Sentence capitalization and punctuation in the comment.
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:94
@@ +93,3 @@
+ // encounter a DeclRefExpr or a CXXConstructExpr.
+ // if it's a DeclRefExpr, we emit a message if the referenced variable is not
+ // a catch variable or function parameter
----------------
Sentence capitalization and punctuation in the comment.
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:121
@@ +120,3 @@
+ auto *currentSubExpr = (*argIter)->IgnoreImpCasts();
+ // if the subexpr is now a DeclRefExpr, it's a real variable and we emit a
+ // diagnosis message.
----------------
Sentence capitalization and punctuation in the comment.
================
Comment at: clang-tidy/misc/ThrowByValueCatchByReferenceCheck.cpp:143
@@ +142,3 @@
+ auto *varDecl = catchStmt->getExceptionDecl();
+ if (caughtType->isPointerType()) {
+ // We do not diagnose when catching pointer to strings since we also allow
----------------
I think this would be better as:
```
if (const auto *PT = caughtType.getCanonicalType()->getAs<PointerType>()) {
if (...)
diag(...);
} else if (!caughtType->isReferenceType() && !caughtType.isTrivialType(context))
diag(...);
```
As-written, it currently checks whether the caught type is a pointer, but not whether the canonical caught type is a pointer.
================
Comment at: test/clang-tidy/misc-throw-by-value-catch-by-reference.cpp:45
@@ +44,3 @@
+
+ // can be enabled once std::move can be included
+ throw move(lvalue);
----------------
This comment is outdated.
http://reviews.llvm.org/D11328
More information about the cfe-commits
mailing list