diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-02 23:27:11 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2012-03-02 23:27:11 +0000 |
commit | a3ca41f0c2bd1c4a752df88b283332f3b757d21e (patch) | |
tree | 8aab234057f7a0c60c5d1bc20ad31ebb07d5977e /test/CodeGenCXX/const-init-cxx11.cpp | |
parent | 067cc40308a9643400fd291fc8678c4a6785e90c (diff) |
Reinstate r151879, r151880, reverted in r151922, along with a bugfix for
scalar emission of DeclRefExprs to const bools: emit scalar bools as i1,
not as i8.
In addition to the extra unit testing, this has successfully bootstrapped.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@151955 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/const-init-cxx11.cpp')
-rw-r--r-- | test/CodeGenCXX/const-init-cxx11.cpp | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/test/CodeGenCXX/const-init-cxx11.cpp b/test/CodeGenCXX/const-init-cxx11.cpp index 5366d6d485..a1486c1175 100644 --- a/test/CodeGenCXX/const-init-cxx11.cpp +++ b/test/CodeGenCXX/const-init-cxx11.cpp @@ -337,3 +337,75 @@ namespace VirtualBase { X<D> x; // CHECK: call {{.*}}@_ZN11VirtualBase1XINS_1DEEC1Ev } + +// PR12145 +namespace Unreferenced { + int n; + constexpr int *p = &n; + // We must not emit a load of 'p' here, since it's not odr-used. + int q = *p; + // CHECK-NOT: _ZN12Unreferenced1pE + // CHECK: = load i32* @_ZN12Unreferenced1nE + // CHECK-NEXT: store i32 {{.*}}, i32* @_ZN12Unreferenced1qE + // CHECK-NOT: _ZN12Unreferenced1pE + + // Technically, we are not required to substitute variables of reference types + // initialized by constant expressions, because the special case for odr-use + // of variables in [basic.def.odr]p2 only applies to objects. But we do so + // anyway. + + constexpr int &r = n; + // CHECK-NOT: _ZN12Unreferenced1rE + int s = r; + + const int t = 1; + const int &rt = t; + int f(int); + int u = f(rt); + // CHECK: call i32 @_ZN12Unreferenced1fEi(i32 1) +} + +namespace InitFromConst { + template<typename T> void consume(T); + + const bool b = true; + const int n = 5; + const double d = 4.3; + + struct S { int n = 7; S *p = 0; }; + constexpr S s = S(); + const S &r = s; + constexpr const S *p = &r; + constexpr int S::*mp = &S::n; + constexpr int a[3] = { 1, 4, 9 }; + + void test() { + // CHECK: call void @_ZN13InitFromConst7consumeIbEEvT_(i1 zeroext true) + consume(b); + + // CHECK: call void @_ZN13InitFromConst7consumeIiEEvT_(i32 5) + consume(n); + + // CHECK: call void @_ZN13InitFromConst7consumeIdEEvT_(double 4.300000e+00) + consume(d); + + // CHECK: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE) + consume<const S&>(s); + + // FIXME CHECK-NOT: call void @_ZN13InitFromConst7consumeIRKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE) + // There's no lvalue-to-rvalue conversion here, so 'r' is odr-used, and + // we're permitted to emit a load of it. This seems likely to be a defect + // in the standard. If we start emitting a direct reference to 's', update + // this test. + consume<const S&>(r); + + // CHECK: call void @_ZN13InitFromConst7consumeIPKNS_1SEEEvT_(%"struct.InitFromConst::S"* @_ZN13InitFromConstL1sE) + consume(p); + + // CHECK: call void @_ZN13InitFromConst7consumeIMNS_1SEiEEvT_(i64 0) + consume(mp); + + // CHECK: call void @_ZN13InitFromConst7consumeIPKiEEvT_(i32* getelementptr inbounds ([3 x i32]* @_ZN13InitFromConstL1aE, i32 0, i32 0)) + consume(a); + } +} |