[cfe-commits] r125447 - in /cfe/trunk: include/clang/AST/Type.h lib/AST/Type.cpp lib/CodeGen/CGCXX.cpp test/CodeGenCXX/destructors.cpp

John McCall rjmccall at apple.com
Sat Feb 12 16:46:43 PST 2011


Author: rjmccall
Date: Sat Feb 12 18:46:43 2011
New Revision: 125447

URL: http://llvm.org/viewvc/llvm-project?rev=125447&view=rev
Log:
Look through array types when deciding whether a field requires non-trivial
destruction in the destructor-aliases logic.  Fixes PR 9197.


Modified:
    cfe/trunk/include/clang/AST/Type.h
    cfe/trunk/lib/AST/Type.cpp
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/test/CodeGenCXX/destructors.cpp

Modified: cfe/trunk/include/clang/AST/Type.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Type.h?rev=125447&r1=125446&r2=125447&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Type.h (original)
+++ cfe/trunk/include/clang/AST/Type.h Sat Feb 12 18:46:43 2011
@@ -692,6 +692,19 @@
     return getObjCGCAttr() == Qualifiers::Strong;
   }
 
+  enum DestructionKind {
+    DK_none,
+    DK_cxx_destructor
+  };
+
+  /// isDestructedType - nonzero if objects of this type require
+  /// non-trivial work to clean up after.  Non-zero because it's
+  /// conceivable that qualifiers (objc_gc(weak)?) could make
+  /// something require destruction.
+  DestructionKind isDestructedType() const {
+    return isDestructedTypeImpl(*this);
+  }
+
 private:
   // These methods are implemented in a separate translation unit;
   // "static"-ize them to avoid creating temporary QualTypes in the
@@ -701,6 +714,7 @@
   static SplitQualType getSplitDesugaredType(QualType T);
   static SplitQualType getSplitUnqualifiedTypeImpl(QualType type);
   static QualType IgnoreParens(QualType T);
+  static DestructionKind isDestructedTypeImpl(QualType type);
 };
 
 } // end clang.

Modified: cfe/trunk/lib/AST/Type.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Type.cpp?rev=125447&r1=125446&r2=125447&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Type.cpp (original)
+++ cfe/trunk/lib/AST/Type.cpp Sat Feb 12 18:46:43 2011
@@ -1576,3 +1576,14 @@
 
   return false;
 }
+
+QualType::DestructionKind QualType::isDestructedTypeImpl(QualType type) {
+  /// Currently, the only destruction kind we recognize is C++ objects
+  /// with non-trivial destructors.
+  const CXXRecordDecl *record =
+    type->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
+  if (record && !record->hasTrivialDestructor())
+    return DK_cxx_destructor;
+
+  return DK_none;
+}

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=125447&r1=125446&r2=125447&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Sat Feb 12 18:46:43 2011
@@ -60,13 +60,12 @@
     return true;
   }
 
-  // If any fields have a non-trivial destructor, we have to emit it
-  // separately.
+  // If any field has a non-trivial destructor, we have to emit the
+  // destructor separately.
   for (CXXRecordDecl::field_iterator I = Class->field_begin(),
          E = Class->field_end(); I != E; ++I)
-    if (const RecordType *RT = (*I)->getType()->getAs<RecordType>())
-      if (!cast<CXXRecordDecl>(RT->getDecl())->hasTrivialDestructor())
-        return true;
+    if ((*I)->getType().isDestructedType())
+      return true;
 
   // Try to find a unique base class with a non-trivial destructor.
   const CXXRecordDecl *UniqueBase = 0;

Modified: cfe/trunk/test/CodeGenCXX/destructors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/destructors.cpp?rev=125447&r1=125446&r2=125447&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/destructors.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/destructors.cpp Sat Feb 12 18:46:43 2011
@@ -306,6 +306,26 @@
   // CHECK:   invoke void @_ZN5test61BILj0EED2Ev
 }
 
+// PR 9197
+namespace test7 {
+  struct D { ~D(); };
+
+  struct A { ~A(); };
+  A::~A() { }
+
+  struct B : public A {
+    ~B();
+    D arr[1];
+  };
+
+  // Verify that this doesn't get emitted as an alias
+  // CHECK: define void @_ZN5test71BD2Ev(
+  // CHECK:   invoke void @_ZN5test71DD1Ev(
+  // CHECK:   call void @_ZN5test71AD2Ev(
+  B::~B() {}
+
+}
+
 // Checks from test3:
 
   // CHECK: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(%"struct.test3::<anonymous namespace>::D"* %this) unnamed_addr





More information about the cfe-commits mailing list