Make sure we unique static-local decls across multiple emissions of
the function body, but do so in a way that doesn't make any assumptions
about the static local actually having a proper, unique mangling,
since apparently we don't do that correctly at all.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153776 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp
index a96cb7a..7e840f5 100644
--- a/test/CodeGenCXX/static-init.cpp
+++ b/test/CodeGenCXX/static-init.cpp
@@ -3,6 +3,7 @@
 // CHECK: @_ZZ1hvE1i = internal global i32 0, align 4
 // CHECK: @base_req = global [4 x i8] c"foo\00", align 1
 
+// CHECK: @_ZZN5test31BC1EvE1u = internal global { i8, [3 x i8] } { i8 97, [3 x i8] undef }, align 4
 // CHECK: @_ZZN5test1L6getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16
 // CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0
 // CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0
@@ -79,3 +80,73 @@
     c::main();
   }
 }
+
+// rdar://problem/11091093
+//   Static variables should be consistent across constructor
+//   or destructor variants.
+namespace test2 {
+  struct A {
+    A();
+    ~A();
+  };
+
+  struct B : virtual A {
+    B();
+    ~B();
+  };
+
+  // If we ever implement this as a delegate ctor call, just change
+  // this to take variadic arguments or something.
+  extern int foo();
+  B::B() {
+    static int x = foo();
+  }
+  // CHECK: define void @_ZN5test21BC1Ev
+  // CHECK:   load atomic i8* bitcast (i64* @_ZGVZN5test21BC1EvE1x to i8*) acquire,
+  // CHECK:   call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BC1EvE1x)
+  // CHECK:   [[T0:%.*]] = call i32 @_ZN5test23fooEv()
+  // CHECK:   store i32 [[T0]], i32* @_ZZN5test21BC1EvE1x,
+  // CHECK:   call void @__cxa_guard_release(i64* @_ZGVZN5test21BC1EvE1x)
+
+  // CHECK: define void @_ZN5test21BC2Ev
+  // CHECK:   load atomic i8* bitcast (i64* @_ZGVZN5test21BC1EvE1x to i8*) acquire,
+  // CHECK:   call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BC1EvE1x)
+  // CHECK:   [[T0:%.*]] = call i32 @_ZN5test23fooEv()
+  // CHECK:   store i32 [[T0]], i32* @_ZZN5test21BC1EvE1x,
+  // CHECK:   call void @__cxa_guard_release(i64* @_ZGVZN5test21BC1EvE1x)
+
+  // This is just for completeness, because we actually emit this
+  // using a delegate dtor call.
+  B::~B() {
+    static int y = foo();
+  }
+  // CHECK: define void @_ZN5test21BD1Ev(
+  // CHECK:   call void @_ZN5test21BD2Ev(
+
+  // CHECK: define void @_ZN5test21BD2Ev(
+  // CHECK:   load atomic i8* bitcast (i64* @_ZGVZN5test21BD1EvE1y to i8*) acquire,
+  // CHECK:   call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BD1EvE1y)
+  // CHECK:   [[T0:%.*]] = call i32 @_ZN5test23fooEv()
+  // CHECK:   store i32 [[T0]], i32* @_ZZN5test21BD1EvE1y,
+  // CHECK:   call void @__cxa_guard_release(i64* @_ZGVZN5test21BD1EvE1y)
+}
+
+// This shouldn't error out.
+namespace test3 {
+  struct A {
+    A();
+    ~A();
+  };
+
+  struct B : virtual A {
+    B();
+    ~B();
+  };
+
+  B::B() {
+    union U { char x; int i; };
+    static U u = { 'a' };
+  }
+  // CHECK: define void @_ZN5test31BC1Ev(
+  // CHECK: define void @_ZN5test31BC2Ev(
+}