summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema/AnalysisBasedWarnings.cpp
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2018-01-13 05:05:45 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2018-01-13 05:05:45 +0000
commit56ae0a67e8207e39b45ea9f19c6855a925189bb4 (patch)
tree888ed7e16a56df27af3fe0350e3efb619e954d98 /clang/lib/Sema/AnalysisBasedWarnings.cpp
parentb22d170caf3d2e344cb51ded85c9f52dafaad9f3 (diff)
downloadbcm5719-llvm-56ae0a67e8207e39b45ea9f19c6855a925189bb4.tar.gz
bcm5719-llvm-56ae0a67e8207e39b45ea9f19c6855a925189bb4.zip
DR126: partially implement the const-correct rules for exception handler matching.
While here, fix up the myriad other ways in which Sema's two "can this handler catch that exception?" implementations get things wrong and unify them. llvm-svn: 322431
Diffstat (limited to 'clang/lib/Sema/AnalysisBasedWarnings.cpp')
-rw-r--r--clang/lib/Sema/AnalysisBasedWarnings.cpp53
1 files changed, 13 insertions, 40 deletions
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 0033edf326a..e67f94c6383 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -287,48 +287,21 @@ enum ThrowState {
FoundPathWithNoThrowOutFunction,
};
-static bool isThrowCaught(const CXXThrowExpr *Throw,
- const CXXCatchStmt *Catch) {
- const Type *CaughtType = Catch->getCaughtType().getTypePtrOrNull();
- if (!CaughtType)
- return true;
- const Type *ThrowType = nullptr;
- if (Throw->getSubExpr())
- ThrowType = Throw->getSubExpr()->getType().getTypePtrOrNull();
- if (!ThrowType)
- return false;
- if (ThrowType->isReferenceType())
- ThrowType = ThrowType->castAs<ReferenceType>()
- ->getPointeeType()
- ->getUnqualifiedDesugaredType();
- if (CaughtType->isReferenceType())
- CaughtType = CaughtType->castAs<ReferenceType>()
- ->getPointeeType()
- ->getUnqualifiedDesugaredType();
- if (ThrowType->isPointerType() && CaughtType->isPointerType()) {
- ThrowType = ThrowType->getPointeeType()->getUnqualifiedDesugaredType();
- CaughtType = CaughtType->getPointeeType()->getUnqualifiedDesugaredType();
- }
- if (CaughtType == ThrowType)
- return true;
- const CXXRecordDecl *CaughtAsRecordType =
- CaughtType->getAsCXXRecordDecl();
- const CXXRecordDecl *ThrowTypeAsRecordType = ThrowType->getAsCXXRecordDecl();
- if (CaughtAsRecordType && ThrowTypeAsRecordType)
- return ThrowTypeAsRecordType->isDerivedFrom(CaughtAsRecordType);
- return false;
-}
-
-static bool isThrowCaughtByHandlers(const CXXThrowExpr *CE,
+static bool isThrowCaughtByHandlers(Sema &S,
+ const CXXThrowExpr *CE,
const CXXTryStmt *TryStmt) {
for (unsigned H = 0, E = TryStmt->getNumHandlers(); H < E; ++H) {
- if (isThrowCaught(CE, TryStmt->getHandler(H)))
+ QualType Caught = TryStmt->getHandler(H)->getCaughtType();
+ if (Caught.isNull() || // catch (...) catches everything
+ (CE->getSubExpr() && // throw; is only caught by ...
+ S.handlerCanCatch(Caught, CE->getSubExpr()->getType())))
return true;
}
return false;
}
-static bool doesThrowEscapePath(CFGBlock Block, SourceLocation &OpLoc) {
+static bool doesThrowEscapePath(Sema &S, CFGBlock Block,
+ SourceLocation &OpLoc) {
for (const auto &B : Block) {
if (B.getKind() != CFGElement::Statement)
continue;
@@ -342,7 +315,7 @@ static bool doesThrowEscapePath(CFGBlock Block, SourceLocation &OpLoc) {
continue;
if (const auto *Terminator =
dyn_cast_or_null<CXXTryStmt>(I->getTerminator()))
- if (isThrowCaughtByHandlers(CE, Terminator))
+ if (isThrowCaughtByHandlers(S, CE, Terminator))
return false;
}
return true;
@@ -350,8 +323,8 @@ static bool doesThrowEscapePath(CFGBlock Block, SourceLocation &OpLoc) {
return false;
}
-static bool hasThrowOutNonThrowingFunc(SourceLocation &OpLoc, CFG *BodyCFG) {
-
+static bool hasThrowOutNonThrowingFunc(Sema &S, SourceLocation &OpLoc,
+ CFG *BodyCFG) {
unsigned ExitID = BodyCFG->getExit().getBlockID();
SmallVector<ThrowState, 16> States(BodyCFG->getNumBlockIDs(),
@@ -369,7 +342,7 @@ static bool hasThrowOutNonThrowingFunc(SourceLocation &OpLoc, CFG *BodyCFG) {
if (ExitID == ID)
continue;
- if (doesThrowEscapePath(*CurBlock, OpLoc))
+ if (doesThrowEscapePath(S, *CurBlock, OpLoc))
CurState = FoundPathForThrow;
}
@@ -419,7 +392,7 @@ static void checkThrowInNonThrowingFunc(Sema &S, const FunctionDecl *FD,
if (BodyCFG->getExit().pred_empty())
return;
SourceLocation OpLoc;
- if (hasThrowOutNonThrowingFunc(OpLoc, BodyCFG))
+ if (hasThrowOutNonThrowingFunc(S, OpLoc, BodyCFG))
EmitDiagForCXXThrowInNonThrowingFunc(S, OpLoc, FD);
}
OpenPOWER on IntegriCloud