r313948 - Fix tracking of whether a destructor would be deleted.

Richard Smith via cfe-commits cfe-commits at lists.llvm.org
Thu Sep 21 18:04:22 PDT 2017


Author: rsmith
Date: Thu Sep 21 18:04:22 2017
New Revision: 313948

URL: http://llvm.org/viewvc/llvm-project?rev=313948&view=rev
Log:
Fix tracking of whether a destructor would be deleted.

I've been unable to find any cases whose behavior is actually changed by this,
but only because an implicitly deleted destructor also results in it being
impossible to have a trivial (non-deleted) copy constructor, which the place
where this really matters (choosing whether to pass a class in registers)
happens to also check.

Added:
    cfe/trunk/test/CXX/special/class.dtor/p5-implicit.cpp
Modified:
    cfe/trunk/include/clang/AST/DeclCXX.h
    cfe/trunk/lib/Sema/SemaDecl.cpp

Modified: cfe/trunk/include/clang/AST/DeclCXX.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=313948&r1=313947&r2=313948&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/DeclCXX.h (original)
+++ cfe/trunk/include/clang/AST/DeclCXX.h Thu Sep 21 18:04:22 2017
@@ -838,7 +838,10 @@ public:
 
   /// \brief \c true if a defaulted destructor for this class would be deleted.
   bool defaultedDestructorIsDeleted() const {
-    return !data().DefaultedDestructorIsDeleted;
+    assert((!needsOverloadResolutionForDestructor() ||
+            (data().DeclaredSpecialMembers & SMF_Destructor)) &&
+           "this property has not yet been computed by Sema");
+    return data().DefaultedDestructorIsDeleted;
   }
 
   /// \brief \c true if we know for sure that this class has a single,
@@ -985,6 +988,15 @@ public:
     data().DefaultedMoveConstructorIsDeleted = true;
   }
 
+  /// \brief Set that we attempted to declare an implicit destructor,
+  /// but overload resolution failed so we deleted it.
+  void setImplicitDestructorIsDeleted() {
+    assert((data().DefaultedDestructorIsDeleted ||
+            needsOverloadResolutionForDestructor()) &&
+           "destructor should not be deleted");
+    data().DefaultedDestructorIsDeleted = true;
+  }
+
   /// \brief Determine whether this class should get an implicit move
   /// constructor or if any existing special member function inhibits this.
   bool needsImplicitMoveConstructor() const {

Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=313948&r1=313947&r2=313948&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Thu Sep 21 18:04:22 2017
@@ -15119,8 +15119,10 @@ void Sema::ActOnFields(Scope *S, SourceL
     if (CXXRecordDecl *CXXRecord = dyn_cast<CXXRecordDecl>(Record)) {
       auto *Dtor = CXXRecord->getDestructor();
       if (Dtor && Dtor->isImplicit() &&
-          ShouldDeleteSpecialMember(Dtor, CXXDestructor))
+          ShouldDeleteSpecialMember(Dtor, CXXDestructor)) {
+        CXXRecord->setImplicitDestructorIsDeleted();
         SetDeclDeleted(Dtor, CXXRecord->getLocation());
+      }
     }
 
     if (Record->hasAttrs()) {

Added: cfe/trunk/test/CXX/special/class.dtor/p5-implicit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CXX/special/class.dtor/p5-implicit.cpp?rev=313948&view=auto
==============================================================================
--- cfe/trunk/test/CXX/special/class.dtor/p5-implicit.cpp (added)
+++ cfe/trunk/test/CXX/special/class.dtor/p5-implicit.cpp Thu Sep 21 18:04:22 2017
@@ -0,0 +1,21 @@
+// RUN: %clang_cc1 -std=c++11 %s -ast-dump | FileCheck %s
+
+struct A { ~A() = delete; };
+// CHECK-LABEL: CXXRecordDecl {{.*}} struct A
+// CHECK: Destructor trivial user_declared
+
+struct B : A {};
+// CHECK-LABEL: CXXRecordDecl {{.*}} struct B
+// CHECK: Destructor trivial needs_overload_resolution
+
+struct C : B {};
+// CHECK-LABEL: CXXRecordDecl {{.*}} struct C
+// CHECK: Destructor trivial needs_overload_resolution
+
+struct D { ~D(); };
+struct E : D {};
+union U {
+  E e;
+};
+// CHECK-LABEL: CXXRecordDecl {{.*}} union U
+// CHECK: Destructor non_trivial needs_implicit defaulted_is_deleted




More information about the cfe-commits mailing list