[PATCH] D33333: Emit warning when throw exception in destruct or dealloc functions which has a (possible implicit) noexcept specifier
Aaron Ballman via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Tue Jun 13 14:56:40 PDT 2017
aaron.ballman added a reviewer: rsmith.
aaron.ballman added a comment.
Adding Richard to the review for some wider perspective than just mine on the overall design.
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:296
+
+ if (ThrowType->isReferenceType())
+ ThrowType = ThrowType->castAs<ReferenceType>()
----------------
If `ThrowType` can be null, there should be a null pointer check here. If it cannot be null, you should use `getTypePtr()` above instead of `getTypePtrOrNull()`.
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:304
+ ->getUnqualifiedDesugaredType();
+ if (CaughtType == nullptr || CaughtType == ThrowType)
+ return true;
----------------
The check for a null `CaughtType` can be hoisted above the if statements, which can then be simplified.
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:312
+ isCaught = ThrowTypeAsRecordType->isDerivedFrom(CaughtAsRecordType);
+ return isCaught;
+}
----------------
There's really no point to using a local variable for this. You can return `true` above and return `false` here.
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:315
+
+static bool isThrowBeCaughtByHandlers(const CXXThrowExpr *CE,
+ const CXXTryStmt *TryStmt) {
----------------
`isThrowCaughtByHandlers` (drop the Be)
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:317
+ const CXXTryStmt *TryStmt) {
+ for (unsigned H = 0; H < TryStmt->getNumHandlers(); ++H) {
+ const CXXCatchStmt *CS = TryStmt->getHandler(H);
----------------
Can you hoist the `getNumHandlers()` call out? e.g., `for (unsigned H = 0, E = TryStmt->getNumHandlers(); H < E; ++H)`
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:318
+ for (unsigned H = 0; H < TryStmt->getNumHandlers(); ++H) {
+ const CXXCatchStmt *CS = TryStmt->getHandler(H);
+ if (isThrowBeCaught(CE, CS))
----------------
No need for the local variable, can just call `getHandler()` in the call expression.
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:325
+
+static bool doesThrowEscapePath(CFGBlock &Block, SourceLocation *OpLoc) {
+ bool HasThrowOutFunc = false;
----------------
Since `OpLoc` cannot be null, pass it by reference instead.
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:337
+ *OpLoc = CE->getThrowLoc();
+ for (const CFGBlock::AdjacentBlock I : Block.succs())
+ if (I && I->getTerminator() && isa<CXXTryStmt>(I->getTerminator())) {
----------------
This should use `const CFGBlock::AdjacentBlock &` to avoid the copy, but could also use `const auto &` if you wanted (since it's a range-based for loop).
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:338
+ for (const CFGBlock::AdjacentBlock I : Block.succs())
+ if (I && I->getTerminator() && isa<CXXTryStmt>(I->getTerminator())) {
+ const CXXTryStmt *Terminator = cast<CXXTryStmt>(I->getTerminator());
----------------
Instead of testing that `I` can be dereferenced (which is a bit odd since `I` is not a pointer, but uses a conversion operator), can you test `I->isReachable()` instead?
I think a better way to write this might be:
```
if (!I->isReachable())
continue;
if (const CXXTryStmt *Terminator = dyn_cast_or_null<CXXTryStmt>(I->getTerminator())) {
}
```
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:344
+ }
+ return HasThrowOutFunc;
+}
----------------
There's no need for this local variable. You can return `true` here.
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:349
+
+ const unsigned ExitID = cfg->getExit().getBlockID();
+
----------------
We don't usually mark locals as `const` unless it's a pointer or reference.
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:373
+ // changes.
+ for (const CFGBlock::AdjacentBlock I : CurBlock->succs())
+ if (I) {
----------------
Same comment here as above.
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:374
+ for (const CFGBlock::AdjacentBlock I : CurBlock->succs())
+ if (I) {
+ unsigned next_ID = (I)->getBlockID();
----------------
Same comment here as above.
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:375
+ if (I) {
+ unsigned next_ID = (I)->getBlockID();
+ if (next_ID == ExitID && CurState == FoundPathForThrow) {
----------------
You can drop the parens around `I`. Also, `next_ID` should be something like `NextID` per the coding style guidelines.
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:405
+ AnalysisDeclContext &AC) {
+ CFG *cfg = AC.getCFG();
+ if (!cfg)
----------------
`cfg` should be renamed per coding style guidelines. How about `BodyCFG`?
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:416
+static bool isNoexcept(const FunctionDecl *FD) {
+ if (const FunctionProtoType *FPT = FD->getType()->castAs<FunctionProtoType>())
+ if (FPT->getExceptionSpecType() != EST_None &&
----------------
No need for the if statement since `castAs<>` will assert if the function type is not `FunctionProtoType`.
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:290
+
+static bool mayThrowBeCaughted(const CXXThrowExpr *Throw,
+ const CXXCatchStmt *Catch) {
----------------
jyu2 wrote:
> aaron.ballman wrote:
> > Caughted -> Caught
> :-(
This should be `isThrowCaught()` (drop the Be).
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:292
+ const CXXCatchStmt *Catch) {
+ bool MayCaught = false;
+ const auto *ThrowType = Throw->getSubExpr()->getType().getTypePtrOrNull();
----------------
aaron.ballman wrote:
> MayCaught -> IsCaught ?
Should be `IsCaught` by coding convention.
================
Comment at: lib/Sema/AnalysisBasedWarnings.cpp:330
+ continue;
+ const CXXThrowExpr *CE =
+ dyn_cast<CXXThrowExpr>(B.getAs<CFGStmt>()->getStmt());
----------------
aaron.ballman wrote:
> Can use `const auto *` here.
This is marked as done but doesn't appear to have been done.
================
Comment at: test/SemaCXX/warn-throw-out-noexcept-func.cpp:1
+// RUN: %clang_cc1 %s -fdelayed-template-parsing -fcxx-exceptions -fexceptions -fsyntax-only -Wexceptions -verify -std=c++11
+struct A {
----------------
aaron.ballman wrote:
> Please drop the svn auto props.
This does not appear to be done.
https://reviews.llvm.org/D33333
More information about the cfe-commits
mailing list