|  | // RUN: %clang_cc1 -std=c++1y -triple x86_64-linux-gnu -emit-llvm %s -o - | FileCheck %s | 
|  |  | 
|  | struct S { | 
|  | S(); | 
|  | S(S &&); | 
|  | ~S(); | 
|  | }; | 
|  |  | 
|  | void f() { | 
|  | (void) [s(S{})] {}; | 
|  | } | 
|  |  | 
|  | // CHECK-LABEL: define{{.*}} void @_Z1fv( | 
|  | // CHECK: call void @_ZN1SC1Ev( | 
|  | // CHECK: call void @"_ZZ1fvEN3$_0D1Ev"( | 
|  |  | 
|  | // CHECK-LABEL: define internal void @"_ZZ1fvEN3$_0D1Ev"( | 
|  | // CHECK: @"_ZZ1fvEN3$_0D2Ev"( | 
|  |  | 
|  | // D2 at end of file. | 
|  |  | 
|  | void g() { | 
|  | [a(1), b(2)] { return a + b; } (); | 
|  | } | 
|  |  | 
|  | // CHECK-LABEL: define{{.*}} void @_Z1gv( | 
|  | // CHECK: getelementptr inbounds {{.*}}, i32 0, i32 0 | 
|  | // CHECK: store i32 1, ptr | 
|  | // CHECK: getelementptr inbounds {{.*}}, i32 0, i32 1 | 
|  | // CHECK: store i32 2, ptr | 
|  | // CHECK: call noundef i32 @"_ZZ1gvENK3$_0clEv"( | 
|  |  | 
|  | // CHECK-LABEL: define internal noundef i32 @"_ZZ1gvENK3$_0clEv"( | 
|  | // CHECK: getelementptr inbounds {{.*}}, i32 0, i32 0 | 
|  | // CHECK: load i32, ptr | 
|  | // CHECK: getelementptr inbounds {{.*}}, i32 0, i32 1 | 
|  | // CHECK: load i32, ptr | 
|  |  | 
|  | // 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, | 
|  | // CHECK: %[[OUTER:.*]] = alloca | 
|  | // CHECK: store i32 {{.*}}, ptr %[[A_ADDR]], | 
|  | // | 
|  | // Initialize init-capture 'b(a)' by reference. | 
|  | // CHECK: getelementptr inbounds {{.*}}, ptr %[[OUTER]], i32 0, i32 0 | 
|  | // CHECK: store ptr %[[A_ADDR]], ptr {{.*}}, | 
|  | // | 
|  | // Initialize init-capture 'c(a)' by copy. | 
|  | // CHECK: getelementptr inbounds {{.*}}, ptr %[[OUTER]], i32 0, i32 1 | 
|  | // CHECK: load i32, ptr %[[A_ADDR]], | 
|  | // CHECK: store i32 | 
|  | // | 
|  | // CHECK: call noundef i32 @"_ZZ1hiENK3$_0clEv"(ptr {{[^,]*}} %[[OUTER]]) | 
|  | return [&b(a), c(a)] { | 
|  | // CHECK-LABEL: define internal noundef i32 @"_ZZ1hiENK3$_0clEv"( | 
|  | // CHECK: %[[OUTER_ADDR:.*]] = alloca | 
|  | // CHECK: %[[INNER:.*]] = alloca | 
|  | // CHECK: store {{.*}}, ptr %[[OUTER_ADDR]], | 
|  | // | 
|  | // Capture outer 'c' by reference. | 
|  | // CHECK: %[[OUTER:.*]] = load ptr, ptr %[[OUTER_ADDR]] | 
|  | // CHECK: getelementptr inbounds {{.*}}, ptr %[[INNER]], i32 0, i32 0 | 
|  | // CHECK-NEXT: getelementptr inbounds {{.*}}, ptr %[[OUTER]], i32 0, i32 1 | 
|  | // CHECK-NEXT: store ptr % | 
|  | // | 
|  | // Capture outer 'b' by copy. | 
|  | // CHECK: getelementptr inbounds {{.*}}, ptr %[[INNER]], i32 0, i32 1 | 
|  | // CHECK-NEXT: getelementptr inbounds {{.*}}, ptr %[[OUTER]], i32 0, i32 0 | 
|  | // CHECK-NEXT: load ptr, ptr % | 
|  | // CHECK-NEXT: load i32, ptr % | 
|  | // CHECK-NEXT: store i32 | 
|  | // | 
|  | // CHECK: call noundef i32 @"_ZZZ1hiENK3$_0clEvENKUlvE_clEv"(ptr {{[^,]*}} %[[INNER]]) | 
|  | return [=, &c] { | 
|  | // CHECK-LABEL: define internal void @"_ZZ1fvEN3$_0D2Ev"( | 
|  | // CHECK: call void @_ZN1SD1Ev( | 
|  |  | 
|  | // CHECK-LABEL: define internal noundef i32 @"_ZZZ1hiENK3$_0clEvENKUlvE_clEv"( | 
|  | // CHECK: %[[INNER_ADDR:.*]] = alloca | 
|  | // CHECK: store {{.*}}, ptr %[[INNER_ADDR]], | 
|  | // CHECK: %[[INNER:.*]] = load ptr, ptr %[[INNER_ADDR]] | 
|  | // | 
|  | // Load capture of 'b' | 
|  | // CHECK: getelementptr inbounds {{.*}}, ptr %[[INNER]], i32 0, i32 1 | 
|  | // CHECK: load i32, ptr % | 
|  | // | 
|  | // Load capture of 'c' | 
|  | // CHECK: getelementptr inbounds {{.*}}, ptr %[[INNER]], i32 0, i32 0 | 
|  | // CHECK: load ptr, ptr % | 
|  | // CHECK: load i32, ptr % | 
|  | // | 
|  | // CHECK: add nsw i32 | 
|  | return b + c; | 
|  | } (); | 
|  | } (); | 
|  | } | 
|  |  | 
|  | // Ensure we can emit code for init-captures in global lambdas too. | 
|  | auto global_lambda = [a = 0] () mutable { return ++a; }; | 
|  | int get_incremented() { return global_lambda(); } |