]> granicus.if.org Git - clang/commitdiff
[ms-cxxabi] Don't do destructor check on declarations if the dtor is deleted
authorHans Wennborg <hans@hanshq.net>
Tue, 17 Dec 2013 17:49:22 +0000 (17:49 +0000)
committerHans Wennborg <hans@hanshq.net>
Tue, 17 Dec 2013 17:49:22 +0000 (17:49 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@197509 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Sema/SemaDecl.cpp
lib/Sema/SemaDeclCXX.cpp
test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp [new file with mode: 0644]

index 6eb8955dbcabc719daa54fb65f47553eb095aa56..7d9c25ed2ddc6f9c5fb0c37af2774dd0893b1788 100644 (file)
@@ -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.
index 76623a90d56e2285317a6dbe4a150d88b457f27d..117c37b636eb7d5e02113ebaaea2622d70ab4707 100644 (file)
@@ -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/test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp b/test/SemaCXX/microsoft-dtor-lookup-cxx11.cpp
new file mode 100644 (file)
index 0000000..eadb6d5
--- /dev/null
@@ -0,0 +1,13 @@
+// RUN: %clang_cc1 -triple i686-pc-win32 -cxx-abi microsoft -std=c++11 -verify %s\r
+\r
+struct S {\r
+  virtual ~S() = delete; // expected-note {{function has been explicitly marked deleted here}}\r
+  void operator delete(void*, int);\r
+  void operator delete(void*, double);\r
+} s; // expected-error {{attempt to use a deleted function}}\r
+\r
+struct T { // expected-note{{virtual destructor requires an unambiguous, accessible 'operator delete'}}\r
+  virtual ~T() = default; // expected-note {{explicitly defaulted function was implicitly deleted here}}\r
+  void operator delete(void*, int);\r
+  void operator delete(void*, double);\r
+} t; // expected-error {{attempt to use a deleted function}}\r