forked from OSchip/llvm-project
Make sure to check the accessibility of and mark the destructor for the
operand of a throw expression. Fixes PR7281. llvm-svn: 105408
This commit is contained in:
parent
d83e3e7750
commit
91a3d27ec0
|
@ -458,11 +458,28 @@ bool Sema::CheckCXXThrowOperand(SourceLocation ThrowLoc, Expr *&E) {
|
|||
return true;
|
||||
E = Res.takeAs<Expr>();
|
||||
|
||||
// If the exception has class type, we need additional handling.
|
||||
const RecordType *RecordTy = Ty->getAs<RecordType>();
|
||||
if (!RecordTy)
|
||||
return false;
|
||||
CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
|
||||
|
||||
// If we are throwing a polymorphic class type or pointer thereof,
|
||||
// exception handling will make use of the vtable.
|
||||
if (const RecordType *RecordTy = Ty->getAs<RecordType>())
|
||||
MarkVTableUsed(ThrowLoc, cast<CXXRecordDecl>(RecordTy->getDecl()));
|
||||
|
||||
MarkVTableUsed(ThrowLoc, RD);
|
||||
|
||||
// If the class has a non-trivial destructor, we must be able to call it.
|
||||
if (RD->hasTrivialDestructor())
|
||||
return false;
|
||||
|
||||
CXXDestructorDecl *Destructor =
|
||||
const_cast<CXXDestructorDecl*>(RD->getDestructor(Context));
|
||||
if (!Destructor)
|
||||
return false;
|
||||
|
||||
MarkDeclarationReferenced(E->getExprLoc(), Destructor);
|
||||
CheckDestructorAccess(E->getExprLoc(), Destructor,
|
||||
PDiag(diag::err_access_dtor_temp) << Ty);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -420,3 +420,9 @@ namespace test15 {
|
|||
template class B<int>; // expected-note {{in instantiation}}
|
||||
template class B<long>; // expected-note 4 {{in instantiation}}
|
||||
}
|
||||
|
||||
// PR7281
|
||||
namespace test16 {
|
||||
class A { ~A(); }; // expected-note {{declared private here}}
|
||||
void b() { throw A(); } // expected-error{{temporary of type 'test16::A' has private destructor}}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
// RUN: %clang_cc1 %s -emit-llvm-only -verify
|
||||
// PR7281
|
||||
|
||||
class A {
|
||||
public:
|
||||
~A();
|
||||
};
|
||||
class B : public A {
|
||||
void ice_throw();
|
||||
};
|
||||
void B::ice_throw() {
|
||||
throw *this;
|
||||
}
|
||||
|
Loading…
Reference in New Issue