diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-07-26 23:18:30 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-07-26 23:18:30 +0000 |
commit | 87717964933512e9db6999b84b4e59ed21c1c99e (patch) | |
tree | fa63e8ec000257f6962ebcc215e2d6a2d298d000 | |
parent | ebc113d1d33d366e0aa2fb7385c64f5d5e24acb3 (diff) | |
download | bcm5719-llvm-87717964933512e9db6999b84b4e59ed21c1c99e.tar.gz bcm5719-llvm-87717964933512e9db6999b84b4e59ed21c1c99e.zip |
Disable the optimization that skips emission of complete, non-virtual
destructors of abstract classes. It's undefined behavior to actually
call the destructor (e.g., via delete), but the presence of code that
calls this destructor doesn't make the program
ill-formed. Fixes <rdar://problem/9819242>.
llvm-svn: 136180
-rw-r--r-- | clang/lib/CodeGen/CGCXX.cpp | 6 | ||||
-rw-r--r-- | clang/test/CodeGenCXX/abstract-class-ctors-dtors.cpp | 2 |
2 files changed, 2 insertions, 6 deletions
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp index f7f8a1271cd..e1463e98eca 100644 --- a/clang/lib/CodeGen/CGCXX.cpp +++ b/clang/lib/CodeGen/CGCXX.cpp @@ -236,11 +236,7 @@ void CodeGenModule::EmitCXXDestructors(const CXXDestructorDecl *D) { // The destructor used for destructing this as a most-derived class; // call the base destructor and then destructs any virtual bases. - if (!D->getParent()->isAbstract() || D->isVirtual()) { - // We don't need to emit the complete ctor if the class is abstract, - // unless the destructor is virtual and needs to be in the vtable. - EmitGlobal(GlobalDecl(D, Dtor_Complete)); - } + EmitGlobal(GlobalDecl(D, Dtor_Complete)); // The destructor used for destructing this as a base class; ignores // virtual bases. diff --git a/clang/test/CodeGenCXX/abstract-class-ctors-dtors.cpp b/clang/test/CodeGenCXX/abstract-class-ctors-dtors.cpp index e1c1a75e479..012c2231551 100644 --- a/clang/test/CodeGenCXX/abstract-class-ctors-dtors.cpp +++ b/clang/test/CodeGenCXX/abstract-class-ctors-dtors.cpp @@ -9,7 +9,7 @@ struct A { // CHECK-NOT: define void @_ZN1AC1Ev // CHECK: define void @_ZN1AC2Ev -// CHECK-NOT: define void @_ZN1AD1Ev +// CHECK: define void @_ZN1AD1Ev // CHECK: define void @_ZN1AD2Ev A::A() { } |