Test to ensure the function does not have an unresolved or unevaluated exception specification before testing whether the function throws or not. Fixes PR25574.
llvm-svn: 253598
This commit is contained in:
parent
014fb55711
commit
f71c9661df
@ -19,9 +19,12 @@ AST_MATCHER(CXXConstructorDecl, isNoThrowCopyConstructor) {
|
|||||||
if (!Node.isCopyConstructor())
|
if (!Node.isCopyConstructor())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (const auto *FnTy = Node.getType()->getAs<FunctionProtoType>())
|
const auto *FnTy = Node.getType()->getAs<FunctionProtoType>();
|
||||||
|
// Assume the best for any unresolved exception specification.
|
||||||
|
if (isUnresolvedExceptionSpec(FnTy->getExceptionSpecType()))
|
||||||
|
return true;
|
||||||
|
|
||||||
return FnTy->isNothrow(Node.getASTContext());
|
return FnTy->isNothrow(Node.getASTContext());
|
||||||
llvm_unreachable("Copy constructor with no prototype");
|
|
||||||
}
|
}
|
||||||
} // end namespace
|
} // end namespace
|
||||||
|
|
||||||
@ -36,7 +39,6 @@ void ThrownExceptionTypeCheck::registerMatchers(MatchFinder *Finder) {
|
|||||||
isCopyConstructor(), unless(isNoThrowCopyConstructor()))))
|
isCopyConstructor(), unless(isNoThrowCopyConstructor()))))
|
||||||
.bind("expr"))),
|
.bind("expr"))),
|
||||||
this);
|
this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThrownExceptionTypeCheck::check(const MatchFinder::MatchResult &Result) {
|
void ThrownExceptionTypeCheck::check(const MatchFinder::MatchResult &Result) {
|
||||||
|
@ -108,5 +108,20 @@ void f() {
|
|||||||
throw Allocates(); // match, copy constructor throws
|
throw Allocates(); // match, copy constructor throws
|
||||||
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
|
// CHECK-MESSAGES: :[[@LINE-1]]:9: warning: thrown exception type is not nothrow copy constructible
|
||||||
throw OptionallyAllocates(); // ok
|
throw OptionallyAllocates(); // ok
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace PR25574 {
|
||||||
|
struct B {
|
||||||
|
B(const B&) noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct D : B {
|
||||||
|
D();
|
||||||
|
virtual ~D() noexcept;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void f() {
|
||||||
|
throw D();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user