diff options
author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-07-23 22:56:45 +0000 |
---|---|---|
committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-07-23 22:56:45 +0000 |
commit | b68cfed35f46283d6a8df0a96dacc806720384a2 (patch) | |
tree | 14af5485bb7c3f00c60b8b985356df07190ad221 /test/CodeGenCXX/temporaries.cpp | |
parent | fc6962eb2acb82e92637824fd3bb02b28619a195 (diff) |
Support lifetime-extension of conditional temporaries.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@337767 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenCXX/temporaries.cpp')
-rw-r--r-- | test/CodeGenCXX/temporaries.cpp | 98 |
1 files changed, 95 insertions, 3 deletions
diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp index 2eb27e71cb..294ff29a8e 100644 --- a/test/CodeGenCXX/temporaries.cpp +++ b/test/CodeGenCXX/temporaries.cpp @@ -1,5 +1,6 @@ -// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++11 | FileCheck %s -check-prefixes=CHECK,NULL-INVALID -// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++11 -fno-delete-null-pointer-checks | FileCheck %s -check-prefixes=CHECK,NULL-VALID +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++11 | FileCheck %s -check-prefixes=CHECK,NULL-INVALID,CHECK-CXX11 +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++17 | FileCheck %s -check-prefixes=CHECK,NULL-INVALID,CHECK-CXX17 +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=x86_64-apple-darwin9 -std=c++11 -fno-delete-null-pointer-checks | FileCheck %s -check-prefixes=CHECK,NULL-VALID,CHECK-CXX11 namespace PR16263 { const unsigned int n = 1234; @@ -46,7 +47,9 @@ namespace PR20227 { namespace BraceInit { typedef const int &CIR; CIR x = CIR{3}; - // CHECK: @_ZGRN9BraceInit1xE_ = internal constant i32 3 + // CHECK-CXX11: @_ZGRN9BraceInit1xE_ = internal constant i32 3 + // FIXME: This should still be emitted as 'constant' in C++17. + // CHECK-CXX17: @_ZGRN9BraceInit1xE_ = internal global i32 3 // CHECK: @_ZN9BraceInit1xE = constant i32* @_ZGRN9BraceInit1xE_ } @@ -804,3 +807,92 @@ namespace PR14130 { // CHECK: call void @_ZN7PR141301SC1Ei({{.*}} @_ZGRN7PR141301vE_, i32 0) // CHECK: store {{.*}} @_ZGRN7PR141301vE_, {{.*}} @_ZN7PR141301vE } + +namespace Conditional { + struct A {}; + struct B : A { B(); ~B(); }; + struct C : A { C(); ~C(); }; + + void g(); + + // CHECK-LABEL: define {{.*}} @_ZN11Conditional1fEb( + void f(bool b) { + // CHECK: store i1 false, i1* %[[CLEANUP_B:.*]], + // CHECK: store i1 false, i1* %[[CLEANUP_C:.*]], + // CHECK: br i1 + // + // CHECK: call {{.*}} @_ZN11Conditional1BC1Ev( + // CHECK: store i1 true, i1* %[[CLEANUP_B]], + // CHECK: br label + // + // CHECK: call {{.*}} @_ZN11Conditional1CC1Ev( + // CHECK: store i1 true, i1* %[[CLEANUP_C]], + // CHECK: br label + A &&r = b ? static_cast<A&&>(B()) : static_cast<A&&>(C()); + + // CHECK: call {{.*}} @_ZN11Conditional1gEv( + g(); + + // CHECK: load {{.*}} %[[CLEANUP_C]] + // CHECK: br i1 + // CHECK: call {{.*}} @_ZN11Conditional1CD1Ev( + // CHECK: br label + + // CHECK: load {{.*}} %[[CLEANUP_B]] + // CHECK: br i1 + // CHECK: call {{.*}} @_ZN11Conditional1BD1Ev( + // CHECK: br label + } + + struct D { A &&a; }; + // CHECK-LABEL: define {{.*}} @_ZN11Conditional10f_indirectEb( + void f_indirect(bool b) { + // CHECK: store i1 false, i1* %[[CLEANUP_B:.*]], + // CHECK: store i1 false, i1* %[[CLEANUP_C:.*]], + // CHECK: br i1 + // + // CHECK: call {{.*}} @_ZN11Conditional1BC1Ev( + // CHECK: store i1 true, i1* %[[CLEANUP_B]], + // CHECK: br label + // + // CHECK: call {{.*}} @_ZN11Conditional1CC1Ev( + // CHECK: store i1 true, i1* %[[CLEANUP_C]], + // CHECK: br label + D d = b ? D{B()} : D{C()}; + + // In C++17, the expression D{...} directly initializes the 'd' object, so + // lifetime-extending the temporaries to the lifetime of the D object + // extends them past the call to g(). + // + // In C++14 and before, D is move-constructed from the result of the + // conditional expression, so no lifetime extension occurs. + + // CHECK-CXX17: call {{.*}} @_ZN11Conditional1gEv( + + // CHECK: load {{.*}} %[[CLEANUP_C]] + // CHECK: br i1 + // CHECK: call {{.*}} @_ZN11Conditional1CD1Ev( + // CHECK: br label + + // CHECK: load {{.*}} %[[CLEANUP_B]] + // CHECK: br i1 + // CHECK: call {{.*}} @_ZN11Conditional1BD1Ev( + // CHECK: br label + + // CHECK-CXX11: call {{.*}} @_ZN11Conditional1gEv( + g(); + } + + extern bool b; + // CHECK: load {{.*}} @_ZN11Conditional1b + // CHECK: br i1 + // + // CHECK: call {{.*}} @_ZN11Conditional1BC1Ev({{.*}} @_ZGRN11Conditional1rE_) + // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN11Conditional1BD1Ev {{.*}} @_ZGRN11Conditional1rE_, + // CHECK: br label + // + // CHECK: call {{.*}} @_ZN11Conditional1CC1Ev({{.*}} @_ZGRN11Conditional1rE0_) + // CHECK: call {{.*}} @__cxa_atexit({{.*}} @_ZN11Conditional1CD1Ev {{.*}} @_ZGRN11Conditional1rE0_, + // CHECK: br label + A &&r = b ? static_cast<A&&>(B()) : static_cast<A&&>(C()); +} |