r202046 - [Win32 ABI] Defer operator delete checks until vtable is marked used
Hans Wennborg
hans at hanshq.net
Mon Feb 24 07:58:24 PST 2014
Author: hans
Date: Mon Feb 24 09:58:24 2014
New Revision: 202046
URL: http://llvm.org/viewvc/llvm-project?rev=202046&view=rev
Log:
[Win32 ABI] Defer operator delete checks until vtable is marked used
We were previously checking at every destructor declaration, but that was a bit
excessive. Since the deleting destructor is emitted with the vtable, do the
check when the vtable is marked used.
Differential Revision: http://llvm-reviews.chandlerc.com/D2851
Modified:
cfe/trunk/include/clang/AST/DeclCXX.h
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/lib/Sema/SemaDeclCXX.cpp
cfe/trunk/test/CXX/drs/dr2xx.cpp
cfe/trunk/test/CXX/special/class.dtor/p9.cpp
cfe/trunk/test/SemaCXX/microsoft-dtor-lookup.cpp
Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=202046&r1=202045&r2=202046&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Mon Feb 24 09:58:24 2014
@@ -2307,8 +2307,12 @@ public:
bool isImplicitlyDeclared);
static CXXDestructorDecl *CreateDeserialized(ASTContext & C, unsigned ID);
- void setOperatorDelete(FunctionDecl *OD) { OperatorDelete = OD; }
- const FunctionDecl *getOperatorDelete() const { return OperatorDelete; }
+ void setOperatorDelete(FunctionDecl *OD) {
+ cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete = OD;
+ }
+ const FunctionDecl *getOperatorDelete() const {
+ return cast<CXXDestructorDecl>(getFirstDecl())->OperatorDelete;
+ }
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=202046&r1=202045&r2=202046&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon Feb 24 09:58:24 2014
@@ -6290,15 +6290,6 @@ static FunctionDecl* CreateNewFunctionDe
SemaRef.AdjustDestructorExceptionSpec(Record, NewDD);
}
- // The Microsoft ABI requires that we perform the destructor body
- // checks (i.e. operator delete() lookup) at every declaration, as
- // any translation unit may need to emit a deleting destructor.
- if (SemaRef.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
- !Record->isDependentType() && Record->getDefinition() &&
- !Record->isBeingDefined() && !NewDD->isDeleted()) {
- SemaRef.CheckDestructor(NewDD);
- }
-
IsVirtualOkay = true;
return NewDD;
Modified: cfe/trunk/lib/Sema/SemaDeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDeclCXX.cpp?rev=202046&r1=202045&r2=202046&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDeclCXX.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDeclCXX.cpp Mon Feb 24 09:58:24 2014
@@ -4479,15 +4479,6 @@ void Sema::CheckCompletedCXXClass(CXXRec
}
}
}
-
- if (Record->hasUserDeclaredDestructor()) {
- // The Microsoft ABI requires that we perform the destructor body
- // checks (i.e. operator delete() lookup) in any translataion unit, as
- // any translation unit may need to emit a deleting destructor.
- if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
- !Record->getDestructor()->isDeleted())
- CheckDestructor(Record->getDestructor());
- }
}
// C++11 [dcl.constexpr]p8: A constexpr specifier for a non-static member
@@ -12345,6 +12336,18 @@ void Sema::MarkVTableUsed(SourceLocation
// Otherwise, we can early exit.
return;
}
+ } else {
+ // The Microsoft ABI requires that we perform the destructor body
+ // checks (i.e. operator delete() lookup) when the vtable is marked used, as
+ // the deleting destructor is emitted with the vtable, not with the
+ // destructor definition as in the Itanium ABI.
+ // If it has a definition, we do the check at that point instead.
+ if (Context.getTargetInfo().getCXXABI().isMicrosoft() &&
+ Class->hasUserDeclaredDestructor() &&
+ !Class->getDestructor()->isDefined() &&
+ !Class->getDestructor()->isDeleted()) {
+ CheckDestructor(Class->getDestructor());
+ }
}
// Local classes need to have their virtual members marked
Modified: cfe/trunk/test/CXX/drs/dr2xx.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/drs/dr2xx.cpp?rev=202046&r1=202045&r2=202046&view=diff
==============================================================================
--- cfe/trunk/test/CXX/drs/dr2xx.cpp (original)
+++ cfe/trunk/test/CXX/drs/dr2xx.cpp Mon Feb 24 09:58:24 2014
@@ -1,10 +1,6 @@
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -triple %itanium_abi_triple
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -triple %itanium_abi_triple
-// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -triple %itanium_abi_triple
-
-// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -triple %ms_abi_triple -DMSABI
-// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -triple %ms_abi_triple -DMSABI
-// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors -triple %ms_abi_triple -DMSABI
+// RUN: %clang_cc1 -std=c++98 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++11 %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++1y %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
// PR13819 -- __SIZE_TYPE__ is incompatible.
typedef __SIZE_TYPE__ size_t; // expected-error 0-1 {{extension}}
@@ -538,30 +534,17 @@ namespace dr250 { // dr250: yes
namespace dr252 { // dr252: yes
struct A {
-#ifdef MSABI
- // expected-note at +2 {{found}}
-#endif
void operator delete(void*); // expected-note {{found}}
};
struct B {
-#ifdef MSABI
- // expected-note at +2 {{found}}
-#endif
void operator delete(void*); // expected-note {{found}}
};
struct C : A, B {
-#ifdef MSABI
- // expected-error at +2 {{'operator delete' found in multiple base classes}}
-#endif
virtual ~C();
};
C::~C() {} // expected-error {{'operator delete' found in multiple base classes}}
struct D {
-#ifdef MSABI
- // expected-note at +3 {{here}} MSABI
- // expected-error at +3 {{no suitable member 'operator delete'}}
-#endif
void operator delete(void*, int); // expected-note {{here}}
virtual ~D();
};
@@ -577,10 +560,6 @@ namespace dr252 { // dr252: yes
struct F {
// If both functions are available, the first one is a placement delete.
void operator delete(void*, size_t);
-#ifdef MSABI
- // expected-note at +3 {{here}}
- // expected-error at +3 {{attempt to use a deleted function}}
-#endif
void operator delete(void*) = delete; // expected-error 0-1{{extension}} expected-note {{here}}
virtual ~F();
};
Modified: cfe/trunk/test/CXX/special/class.dtor/p9.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.dtor/p9.cpp?rev=202046&r1=202045&r2=202046&view=diff
==============================================================================
--- cfe/trunk/test/CXX/special/class.dtor/p9.cpp (original)
+++ cfe/trunk/test/CXX/special/class.dtor/p9.cpp Mon Feb 24 09:58:24 2014
@@ -29,18 +29,12 @@ namespace test0 {
namespace test1 {
class A {
public:
-#ifdef MSABI
- // expected-note at +2 {{declared here}}
-#endif
static void operator delete(void *p) {}; // expected-note {{member 'operator delete' declared here}}
virtual ~A();
};
class B : protected A {
public:
-#ifdef MSABI
- // expected-note at +2 {{declared here}}
-#endif
static void operator delete(void *, size_t) {}; // expected-note {{member 'operator delete' declared here}}
~B();
};
@@ -50,9 +44,6 @@ namespace test1 {
using A::operator delete;
using B::operator delete;
-#ifdef MSABI
- // expected-error at +2 {{multiple suitable 'operator delete' functions in 'C'}}
-#endif
~C();
};
@@ -62,22 +53,12 @@ namespace test1 {
// ...at the point of definition of a virtual destructor...
namespace test2 {
struct A {
-#ifdef MSABI
- // expected-error at +3 {{no suitable member 'operator delete' in 'A'}}
- // expected-note at +3 {{declared here}}
-#endif
virtual ~A();
static void operator delete(void*, const int &);
};
struct B {
-#ifdef MSABI
- // expected-error at +2 {{no suitable member 'operator delete' in 'B'}}
-#endif
virtual ~B();
-#ifdef MSABI
- // expected-note at +2 {{declared here}}
-#endif
static void operator delete(void*, const int &); // expected-note {{declared here}}
};
B::~B() {} // expected-error {{no suitable member 'operator delete' in 'B'}}
Modified: cfe/trunk/test/SemaCXX/microsoft-dtor-lookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/microsoft-dtor-lookup.cpp?rev=202046&r1=202045&r2=202046&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/microsoft-dtor-lookup.cpp (original)
+++ cfe/trunk/test/SemaCXX/microsoft-dtor-lookup.cpp Mon Feb 24 09:58:24 2014
@@ -1,12 +1,11 @@
// RUN: %clang_cc1 -triple %itanium_abi_triple -fsyntax-only %s
-// RUN: %clang_cc1 -triple %ms_abi_triple -verify -DMSVC_ABI %s
+// RUN: %clang_cc1 -triple %ms_abi_triple -verify %s
namespace Test1 {
// Should be accepted under the Itanium ABI (first RUN line) but rejected
// under the Microsoft ABI (second RUN line), as Microsoft ABI requires
-// operator delete() lookups to be done at all virtual destructor declaration
-// points.
+// operator delete() lookups to be done when vtables are marked used.
struct A {
void operator delete(void *); // expected-note {{member found by ambiguous name lookup}}
@@ -24,6 +23,10 @@ struct VC : A, B {
virtual ~VC(); // expected-error {{member 'operator delete' found in multiple base classes of different types}}
};
+void f(VC vc) {
+ // This marks VC's vtable used.
+}
+
}
namespace Test2 {
More information about the cfe-commits
mailing list