]> granicus.if.org Git - clang/commitdiff
Remove abuse of hasTrivial*, and fix miscompile wherein global arrays with
authorRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 12 Nov 2012 21:38:00 +0000 (21:38 +0000)
committerRichard Smith <richard-llvm@metafoo.co.uk>
Mon, 12 Nov 2012 21:38:00 +0000 (21:38 +0000)
internal linkage, no uses, trivial construction, and nontrivial destruction
were not emitted.

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

lib/AST/ASTContext.cpp
test/CodeGenCXX/global-array-destruction.cpp
test/CodeGenCXX/trivial-constructor-init.cpp

index 2f7288109c0e69fd74454d5c8cd00781572ed082..577dd0adaf2fd362f5c4548263be3c26c2c83bba 100644 (file)
@@ -7446,27 +7446,20 @@ bool ASTContext::DeclMustBeEmitted(const Decl *D) {
   if (VD->isThisDeclarationADefinition() == VarDecl::DeclarationOnly)
     return false;
 
-  // Structs that have non-trivial constructors or destructors are required.
-
-  // FIXME: Handle references.
-  // FIXME: Be more selective about which constructors we care about.
-  if (const RecordType *RT = VD->getType()->getAs<RecordType>()) {
-    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
-      if (RD->hasDefinition() && !(RD->hasTrivialDefaultConstructor() &&
-                                   RD->hasTrivialCopyConstructor() &&
-                                   RD->hasTrivialMoveConstructor() &&
-                                   RD->hasTrivialDestructor()))
-        return true;
-    }
-  }
-
+  // Variables that can be needed in other TUs are required.
   GVALinkage L = GetGVALinkageForVariable(VD);
-  if (L == GVA_Internal || L == GVA_TemplateInstantiation) {
-    if (!(VD->getInit() && VD->getInit()->HasSideEffects(*this)))
-      return false;
-  }
+  if (L != GVA_Internal && L != GVA_TemplateInstantiation)
+    return true;
 
-  return true;
+  // Variables that have destruction with side-effects are required.
+  if (VD->getType().isDestructedType())
+    return true;
+
+  // Variables that have initialization with side-effects are required.
+  if (VD->getInit() && VD->getInit()->HasSideEffects(*this))
+    return true;
+
+  return false;
 }
 
 CallingConv ASTContext::getDefaultCXXMethodCallConv(bool isVariadic) {
index 076ef942201d7f47e467c821c0f7c8fd110d92ee..b86432228cf0bf164e79be9e25c47961a28ff379 100644 (file)
@@ -43,3 +43,11 @@ T t[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
 // CHECK: call void @_ZN1TD1Ev
 // CHECK: icmp eq {{.*}} @t
 // CHECK: br i1 {{.*}}
+
+static T t2[2][3] = { 1.0, 2, 3.0, 4, 5.0, 6, 7.0, 8, 9.0, 10, 11.0, 12 };
+
+// CHECK: call {{.*}} @__cxa_atexit
+// CHECK: getelementptr inbounds ({{.*}} bitcast {{.*}}* @_ZL2t2 to %struct.T*), i64 6
+// CHECK: call void @_ZN1TD1Ev
+// CHECK: icmp eq {{.*}} @_ZL2t
+// CHECK: br i1 {{.*}}
index 343dc6575a71757cb0850561f342264726b1c6c6..4922a9ee090e839604a9366c6547d539914a5277 100644 (file)
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1  -S %s -o %t-64.s
-// RUN: %clang_cc1  -S %s -o %t-32.s
+// RUN: %clang_cc1 -emit-llvm %s -o - -std=c++11 | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm %s -o - -std=c++11 | FileCheck %s
 
 extern "C" int printf(...);
 
@@ -16,5 +16,20 @@ struct A {
 
 A a;
 
+struct B {
+  B() = default;
+  B(const B&);
+};
+
+// CHECK-NOT: _ZL1b
+static B b;
+
+struct C {
+  ~C();
+};
+
+// CHECK: _ZL1c
+static C c[4];
+
 int main() {
 }