summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2013-12-17 17:49:22 +0000
committerHans Wennborg <hans@hanshq.net>2013-12-17 17:49:22 +0000
commite955e3998ffccf7d4f8cca3370f04a35e5ab3d8b (patch)
tree3facf22b6a2ee118ddc168b1e77e73f2eab0944f
parentb4c44d239c95f81777403fd89f39cb7b415c7f48 (diff)
downloadbcm5719-llvm-e955e3998ffccf7d4f8cca3370f04a35e5ab3d8b.tar.gz
bcm5719-llvm-e955e3998ffccf7d4f8cca3370f04a35e5ab3d8b.zip
[ms-cxxabi] Don't do destructor check on declarations if the dtor is deleted
We would previously emit redundant diagnostics for the following code: struct S { virtual ~S() = delete; void operator delete(void*, int); void operator delete(void*, double); } s; First we would check on ~S() and error about the ambigous delete functions, and then we would error about using the deleted destructor. If the destructor is deleted, there's no need to check it. Also, move the check from Sema::ActOnFields to CheckCompleteCXXClass. These are run at almost the same time, called from ActOnFinishCXXMemberSpecification. However, CHeckCompleteCXXClass may mark a defaulted destructor as deleted, and if that's the case we don't want to check it. Differential Revision: http://llvm-reviews.chandlerc.com/D2421 llvm-svn: 197509
-rw-r--r--clang/lib/Sema/SemaDecl.cpp8
-rw-r--r--clang/lib/Sema/SemaDeclCXX.cpp9
-rw-r--r--clang/test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp13
3 files changed, 23 insertions, 7 deletions
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 6eb8955dbca..7d9c25ed2dd 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -6332,7 +6332,7 @@ static FunctionDecl* CreateNewFunctionDecl(Sema &SemaRef, Declarator &D,
// any translation unit may need to emit a deleting destructor.
if (SemaRef.Context.getTargetInfo().getCXXABI().isMicrosoft() &&
!Record->isDependentType() && Record->getDefinition() &&
- !Record->isBeingDefined()) {
+ !Record->isBeingDefined() && !NewDD->isDeleted()) {
SemaRef.CheckDestructor(NewDD);
}
@@ -12082,12 +12082,6 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
if (getLangOpts().CPlusPlus11)
AdjustDestructorExceptionSpec(CXXRecord,
CXXRecord->getDestructor());
-
- // 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 (Context.getTargetInfo().getCXXABI().isMicrosoft())
- CheckDestructor(CXXRecord->getDestructor());
}
// Add any implicitly-declared members to this class.
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index 76623a90d56..117c37b636e 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -4469,6 +4469,15 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) {
}
}
}
+
+ 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
diff --git a/clang/test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp b/clang/test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp
new file mode 100644
index 00000000000..eadb6d510b7
--- /dev/null
+++ b/clang/test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -cxx-abi microsoft -std=c++11 -verify %s
+
+struct S {
+ virtual ~S() = delete; // expected-note {{function has been explicitly marked deleted here}}
+ void operator delete(void*, int);
+ void operator delete(void*, double);
+} s; // expected-error {{attempt to use a deleted function}}
+
+struct T { // expected-note{{virtual destructor requires an unambiguous, accessible 'operator delete'}}
+ virtual ~T() = default; // expected-note {{explicitly defaulted function was implicitly deleted here}}
+ void operator delete(void*, int);
+ void operator delete(void*, double);
+} t; // expected-error {{attempt to use a deleted function}}
OpenPOWER on IntegriCloud