diff options
| author | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-10-19 19:01:34 +0000 |
|---|---|---|
| committer | Richard Smith <richard-llvm@metafoo.co.uk> | 2018-10-19 19:01:34 +0000 |
| commit | b3d203ff7f308cc5675f095654d0cda905bf95bf (patch) | |
| tree | 827f58b9968e6a725ea2d02434ceea1869981c9b /clang/test | |
| parent | 36f62c066a8cd97a0b3459eec11d929ec875c941 (diff) | |
| download | bcm5719-llvm-b3d203ff7f308cc5675f095654d0cda905bf95bf.tar.gz bcm5719-llvm-b3d203ff7f308cc5675f095654d0cda905bf95bf.zip | |
PR24164, PR39336: init-captures are not distinct full-expressions.
Rather, they are subexpressions of the enclosing lambda-expression, and
any temporaries in them are destroyed at the end of that
full-expression, or when the corresponding lambda-expression is
destroyed if they are lifetime-extended.
llvm-svn: 344801
Diffstat (limited to 'clang/test')
| -rw-r--r-- | clang/test/CXX/special/class.temporary/p6.cpp | 52 | ||||
| -rw-r--r-- | clang/test/CodeGenCXX/cxx1y-init-captures.cpp | 13 | ||||
| -rw-r--r-- | clang/test/SemaCXX/cxx1y-init-captures.cpp | 8 |
3 files changed, 68 insertions, 5 deletions
diff --git a/clang/test/CXX/special/class.temporary/p6.cpp b/clang/test/CXX/special/class.temporary/p6.cpp index e8680902165..077385fb7aa 100644 --- a/clang/test/CXX/special/class.temporary/p6.cpp +++ b/clang/test/CXX/special/class.temporary/p6.cpp @@ -1,4 +1,15 @@ -// RUN: %clang_cc1 -std=c++17 %s -emit-llvm -o - | FileCheck %s --implicit-check-not='call{{.*}}dtor' +// RUN: %clang_cc1 -std=c++17 %s -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s --implicit-check-not='call{{.*}}dtor' + +namespace std { + typedef decltype(sizeof(int)) size_t; + + template <class E> + struct initializer_list { + const E *begin; + size_t size; + initializer_list() : begin(nullptr), size(0) {} + }; +} void then(); @@ -8,6 +19,14 @@ struct dtor { dtor ctor(); +auto &&lambda = [a = {ctor()}] {}; +// CHECK-LABEL: define +// CHECK: call {{.*}}ctor +// CHECK: call {{.*}}atexit{{.*}}global_array_dtor + +// CHECK-LABEL: define{{.*}}global_array_dtor +// CHECK: call {{.*}}dtor + // [lifetime extension occurs if the object was obtained by] // -- a temporary materialization conversion // CHECK-LABEL: ref_binding @@ -188,3 +207,34 @@ void comma() { // CHECK: call {{.*}}dtor // CHECK: } } + + +// This applies recursively: if an object is lifetime-extended and contains a +// reference, the referent is also extended. +// CHECK-LABEL: init_capture_ref +void init_capture_ref() { + // CHECK: call {{.*}}ctor + auto x = [&a = (const dtor&)ctor()] {}; + // CHECK: call {{.*}}then + then(); + // CHECK: call {{.*}}dtor + // CHECK: } +} +// CHECK-LABEL: init_capture_ref_indirect +void init_capture_ref_indirect() { + // CHECK: call {{.*}}ctor + auto x = [&a = (const dtor&)ctor()] {}; + // CHECK: call {{.*}}then + then(); + // CHECK: call {{.*}}dtor + // CHECK: } +} +// CHECK-LABEL: init_capture_init_list +void init_capture_init_list() { + // CHECK: call {{.*}}ctor + auto x = [a = {ctor()}] {}; + // CHECK: call {{.*}}then + then(); + // CHECK: call {{.*}}dtor + // CHECK: } +} diff --git a/clang/test/CodeGenCXX/cxx1y-init-captures.cpp b/clang/test/CodeGenCXX/cxx1y-init-captures.cpp index dcfe4d47292..c76180c5bf4 100644 --- a/clang/test/CodeGenCXX/cxx1y-init-captures.cpp +++ b/clang/test/CodeGenCXX/cxx1y-init-captures.cpp @@ -38,6 +38,19 @@ void g() { // CHECK: add nsw i32 +// CHECK-LABEL: define void @_Z18init_capture_dtorsv +void init_capture_dtors() { + // Ensure that init-captures are not treated as separate full-expressions. + struct HasDtor { ~HasDtor() {} }; + void some_function_call(); + void other_function_call(); + // CHECK: call {{.*}}some_function_call + // CHECK: call {{.*}}HasDtorD + ([x = (HasDtor(), 0)]{}, some_function_call()); + // CHECK: call {{.*}}other_function_call + other_function_call(); +} + int h(int a) { // CHECK-LABEL: define i32 @_Z1hi( // CHECK: %[[A_ADDR:.*]] = alloca i32, diff --git a/clang/test/SemaCXX/cxx1y-init-captures.cpp b/clang/test/SemaCXX/cxx1y-init-captures.cpp index 4b82452ed59..16cffb2a914 100644 --- a/clang/test/SemaCXX/cxx1y-init-captures.cpp +++ b/clang/test/SemaCXX/cxx1y-init-captures.cpp @@ -144,13 +144,13 @@ int test(T t = T{}) { }; } { // will need to capture x in outer lambda - const int x = 10; //expected-note 2{{declared}} - auto L = [z = x](char a) { //expected-note 2{{begins}} - auto M = [&y = x](T b) { //expected-error 2{{cannot be implicitly captured}} + const int x = 10; //expected-note {{declared}} + auto L = [z = x](char a) { //expected-note {{begins}} + auto M = [&y = x](T b) { //expected-error {{cannot be implicitly captured}} return y; }; return M; - }; + }; } { // no captures |

