forked from OSchip/llvm-project
Check the access of operator delete from the destructor context
Previously we would do the access check from the context of MarkVTableUsed. Also update this test to C++11, since that is typically used with the MS C++ ABI. Fixes PR20005. llvm-svn: 210850
This commit is contained in:
parent
d90a8746df
commit
6713086bca
|
@ -12462,7 +12462,9 @@ void Sema::MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class,
|
|||
Class->hasUserDeclaredDestructor() &&
|
||||
!Class->getDestructor()->isDefined() &&
|
||||
!Class->getDestructor()->isDeleted()) {
|
||||
CheckDestructor(Class->getDestructor());
|
||||
CXXDestructorDecl *DD = Class->getDestructor();
|
||||
ContextRAII SavedContext(*this, DD);
|
||||
CheckDestructor(DD);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only %s
|
||||
// RUN: %clang_cc1 -triple %ms_abi_triple -verify %s
|
||||
// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++11 -triple %itanium_abi_triple -fsyntax-only %s
|
||||
// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -std=c++11 -triple %ms_abi_triple -verify %s
|
||||
|
||||
namespace Test1 {
|
||||
|
||||
|
@ -37,11 +37,11 @@ namespace Test2 {
|
|||
// though MSVC rejects bar.
|
||||
class A {
|
||||
private:
|
||||
~A(); // expected-note {{declared private here}}
|
||||
~A();
|
||||
int a;
|
||||
};
|
||||
|
||||
struct B : public A { // expected-error {{base class 'Test2::A' has private destructor}}
|
||||
struct B : public A { // expected-note {{destructor of 'B' is implicitly deleted because base class 'Test2::A' has an inaccessible destructor}}
|
||||
int b;
|
||||
};
|
||||
|
||||
|
@ -55,7 +55,7 @@ struct D {
|
|||
C o;
|
||||
};
|
||||
|
||||
void foo(B b) { } // expected-note {{implicit destructor for 'Test2::B' first required here}}
|
||||
void foo(B b) { } // expected-error {{attempt to use a deleted function}}
|
||||
void bar(A a) { } // no error; MSVC rejects this, but we skip the direct access check.
|
||||
void baz(D d) { } // no error
|
||||
|
||||
|
@ -87,3 +87,45 @@ namespace Test4 {
|
|||
class A;
|
||||
void foo(A a);
|
||||
}
|
||||
|
||||
#ifdef MSVC_ABI
|
||||
namespace Test5 {
|
||||
// Do the operator delete access control check from the context of the dtor.
|
||||
class A {
|
||||
protected:
|
||||
void operator delete(void *);
|
||||
};
|
||||
class B : public A {
|
||||
virtual ~B();
|
||||
};
|
||||
B *test() {
|
||||
// Previously, marking the vtable used here would do the operator delete
|
||||
// lookup from this context, which doesn't have access.
|
||||
return new B;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
namespace Test6 {
|
||||
class A {
|
||||
protected:
|
||||
void operator delete(void *);
|
||||
};
|
||||
class B : public A {
|
||||
virtual ~B();
|
||||
public:
|
||||
virtual void m_fn1();
|
||||
};
|
||||
void fn1(B *b) { b->m_fn1(); }
|
||||
}
|
||||
|
||||
namespace Test7 {
|
||||
class A {
|
||||
protected:
|
||||
void operator delete(void *);
|
||||
};
|
||||
struct B : public A {
|
||||
virtual ~B();
|
||||
};
|
||||
void fn1(B b) {}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue