]> granicus.if.org Git - clang/commitdiff
If a global initializer has a non-trivial constructor or destructor, we never want...
authorAnders Carlsson <andersca@mac.com>
Thu, 8 Oct 2009 17:28:59 +0000 (17:28 +0000)
committerAnders Carlsson <andersca@mac.com>
Thu, 8 Oct 2009 17:28:59 +0000 (17:28 +0000)
With this change we're finally able to compile and run the (infamous)

#include <string>
#include <iostream>

int main(int argc, char **argv) {
  std::cout << "Hello, World" << std::endl;
}

$ clang hello.cpp -lstdc++ -o hello
$ ./hello
Hello, World

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

lib/CodeGen/CodeGenModule.cpp
test/CodeGenCXX/global-init.cpp

index 246beaa403405a624cd26f2e9e621b374437de30..800600f4b78bd8e345c0fef5ee9d968e55975c28 100644 (file)
@@ -531,6 +531,17 @@ bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
   const VarDecl *VD = cast<VarDecl>(Global);
   assert(VD->isFileVarDecl() && "Invalid decl");
 
+  // We never want to defer structs that have non-trivial constructors or 
+  // destructors.
+  
+  // FIXME: Handle references.
+  if (const RecordType *RT = VD->getType()->getAs<RecordType>()) {
+    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+      if (!RD->hasTrivialConstructor() || !RD->hasTrivialDestructor())
+        return false;
+    }
+  }
+      
   return VD->getStorageClass() == VarDecl::Static;
 }
 
index ea6b1e7eb62b995801fda0dc3eb9b3a549a8cba0..ae450e17e85ebbd60882923a3a227579930e5fdf 100644 (file)
@@ -1,10 +1,16 @@
-// RUN: clang-cc -triple=x86_64-apple-darwin9 -emit-llvm %s -o - |FileCheck %s
+// RUN: clang-cc -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck %s
 
 struct A {
   A();
   ~A();
 };
 
-// CHECK: call void @_ZN1AC1Ev
+struct B { B(); ~B(); };
+
+// CHECK: call void @_ZN1AC1Ev(%struct.A* @a)
 // CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @a, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
 A a;
+
+// CHECK: call void @_ZN1BC1Ev(%struct.A* @b)
+// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1BD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @b, i32 0, i32 0), i8* bitcast (i8** @__dso_handle to i8*))
+B b;