teak-llvm/clang/test/CodeGenCXX/const-init-cxx1y.cpp
David Majnemer c9a9c7a673 CodeGen: static constexpr data members should have a linkonce_odr init
Classes can be defined in multiple translation units.  This means that
the static constexpr data members should have identical initializers in
all translation units.  Implement this by giving the reference temporary
linkonce_odr linkage.

llvm-svn: 229900
2015-02-19 19:25:17 +00:00

88 lines
4.0 KiB
C++

// RUN: %clang_cc1 -verify -triple x86_64-apple-darwin -emit-llvm -o - %s -std=c++1y | FileCheck %s
// expected-no-diagnostics
struct A {
constexpr A() : n(1) {}
~A();
int n;
};
struct B : A {
A a[3];
constexpr B() {
++a[0].n;
a[1].n += 2;
a[2].n = n + a[1].n;
}
};
B b;
// CHECK: @b = global {{.*}} i32 1, {{.*}} { i32 2 }, {{.*}} { i32 3 }, {{.*}} { i32 4 }
// CHECK-NOT: _ZN1BC
namespace ModifyStaticTemporary {
struct A { int &&temporary; int x; };
constexpr int f(int &r) { r *= 9; return r - 12; }
A a = { 6, f(a.temporary) };
// CHECK: @_ZGRN21ModifyStaticTemporary1aE_ = internal global i32 54
// CHECK: @_ZN21ModifyStaticTemporary1aE = global {{.*}} i32* @_ZGRN21ModifyStaticTemporary1aE_, i32 42
A b = { 7, ++b.temporary };
// CHECK: @_ZGRN21ModifyStaticTemporary1bE_ = internal global i32 8
// CHECK: @_ZN21ModifyStaticTemporary1bE = global {{.*}} i32* @_ZGRN21ModifyStaticTemporary1bE_, i32 8
// Can't emit all of 'c' as a constant here, so emit the initial value of
// 'c.temporary', not the value as modified by the partial evaluation within
// the initialization of 'c.x'.
A c = { 10, (++c.temporary, b.x) };
// CHECK: @_ZGRN21ModifyStaticTemporary1cE_ = internal global i32 10
// CHECK: @_ZN21ModifyStaticTemporary1cE = global {{.*}} zeroinitializer
}
// CHECK: @_ZGRN28VariableTemplateWithConstRef1iIvEE_ = linkonce_odr constant i32 5, align 4
// CHECK: @_ZN28VariableTemplateWithConstRef3useE = constant i32* @_ZGRN28VariableTemplateWithConstRef1iIvEE_
namespace VariableTemplateWithConstRef {
template <typename T>
const int &i = 5;
const int &use = i<void>;
}
// CHECK: @_ZGRN34HiddenVariableTemplateWithConstRef1iIvEE_ = linkonce_odr hidden constant i32 5, align 4
// CHECK: @_ZN34HiddenVariableTemplateWithConstRef3useE = constant i32* @_ZGRN34HiddenVariableTemplateWithConstRef1iIvEE_
namespace HiddenVariableTemplateWithConstRef {
template <typename T>
__attribute__((visibility("hidden"))) const int &i = 5;
const int &use = i<void>;
}
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE1_ = linkonce_odr constant i32 1
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE0_ = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE1_ }
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE3_ = linkonce_odr constant i32 2
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE2_ = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE3_ }
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE5_ = linkonce_odr constant i32 3
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE4_ = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE5_ }
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE7_ = linkonce_odr constant i32 4
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE6_ = linkonce_odr global {{.*}} { i32* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE7_ }
// CHECK: @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE_ = linkonce_odr global %"struct.VariableTemplateWithPack::S" { {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE0_, {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE2_, {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE4_, {{.*}}* @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE6_ }
// CHECK: @_ZN24VariableTemplateWithPack1pE = global {{.*}} @_ZGRN24VariableTemplateWithPack1sIJLi1ELi2ELi3ELi4EEEE_
namespace VariableTemplateWithPack {
struct A {
const int &r;
};
struct S {
A &&a, &&b, &&c, &&d;
};
template <int... N>
S &&s = {A{N}...};
S *p = &s<1, 2, 3, 4>;
}
// CHECK: __cxa_atexit({{.*}} @_ZN1BD1Ev {{.*}} @b
// CHECK: define
// CHECK-NOT: @_ZGRN21ModifyStaticTemporary1cE_
// CHECK: store {{.*}} @_ZGRN21ModifyStaticTemporary1cE_, {{.*}} @_ZN21ModifyStaticTemporary1cE
// CHECK: add
// CHECK: store
// CHECK: load {{.*}} @_ZN21ModifyStaticTemporary1bE
// CHECK: store {{.*}} @_ZN21ModifyStaticTemporary1cE