// RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-linux -o - | FileCheck %s struct TrivialStruct { void explicit_object_function(this TrivialStruct) {} }; void test() { TrivialStruct s; s.explicit_object_function(); } // CHECK: define {{.*}}test{{.*}} // CHECK-NEXT: entry: // CHECK: {{.*}} = alloca %struct.TrivialStruct, align 1 // CHECK: {{.*}} = alloca %struct.TrivialStruct, align 1 // CHECK: call void {{.*}}explicit_object_function{{.*}} // CHECK-NEXT: ret void // CHECK-NEXT: } // CHECK: define {{.*}}explicit_object_function{{.*}} // CHECK-NEXT: entry: // CHECK: {{.*}} = alloca %struct.TrivialStruct, align 1 // CHECK: ret void // CHECK-NEXT: } void test_lambda() { [](this auto This) -> int { return This(); }(); } //CHECK: define dso_local void @{{.*}}test_lambda{{.*}}() #0 { //CHECK: entry: //CHECK: %agg.tmp = alloca %class.anon, align 1 //CHECK: %ref.tmp = alloca %class.anon, align 1 //CHECK: %call = call noundef i32 @"_ZZ11test_lambdavENH3$_0clIS_EEiT_"() //CHECK: ret void //CHECK: } //CHECK: define internal noundef i32 @"_ZZ11test_lambdavENH3$_0clIS_EEiT_"() #0 align 2 { //CHECK: entry: //CHECK: %This = alloca %class.anon, align 1 //CHECK: %agg.tmp = alloca %class.anon, align 1 //CHECK: %call = call noundef i32 @"_ZZ11test_lambdavENH3$_0clIS_EEiT_"() //CHECK: ret i32 %call //CHECK: } void test_lambda_ref() { auto l = [i = 42](this auto & This, int j) -> int { return This(j); }; l(0); } // CHECK: define dso_local void @_Z15test_lambda_refv() #0 { // CHECK: entry: // CHECK: %[[This_address:.]] = alloca %class.anon{{.*}}, align 4 // CHECK: %[[i_addr:.*]] = getelementptr inbounds %class.anon{{.*}}, ptr %[[This_address]], i32 0, i32 0 // CHECK: store i32 42, ptr %[[i_addr]], align 4 // CHECK: %call = call noundef i32 @"_ZZ15test_lambda_refvENH3$_0clIS_EEiRT_i"{{.*}} // CHECK: ret void // CHECK: } // CHECK: define internal noundef i32 @"_ZZ15test_lambda_refvENH3$_0clIS_EEiRT_i"{{.*}} // CHECK: entry: // CHECK: %This.addr = alloca ptr, align 8 // CHECK: %j.addr = alloca i32, align 4 // CHECK: store ptr %This, ptr %This.addr, align 8 // CHECK: store i32 %j, ptr %j.addr, align 4 // CHECK: %[[this_addr:.*]] = load ptr, ptr %This.addr, align 8 // CHECK: %[[j_addr:.*]] = load i32, ptr %j.addr, align 4 // CHECK: %call = call noundef i32 @"_ZZ15test_lambda_refvENH3$_0clIS_EEiRT_i"(ptr noundef nonnull align 4 dereferenceable(4) %[[this_addr]], i32 noundef %[[j_addr]]) // CHECK: ret i32 %call // CHECK: } struct TestPointer { void f(this TestPointer &); }; void test_pointer() { TestPointer t; using Fn = void(TestPointer&); Fn* fn = &TestPointer::f; fn(t); } //CHECK: define dso_local void @_Z12test_pointerv() #0 { //CHECK-NEXT: entry: //CHECK-NEXT: %t = alloca %struct.TestPointer, align 1 //CHECK-NEXT: %fn = alloca ptr, align 8 //CHECK-NEXT: store ptr @_ZNH11TestPointer1fERS_, ptr %fn, align 8 //CHECK: %[[fn_ptr:.*]] = load ptr, ptr %fn, align 8 //CHECK-NEXT: call void %[[fn_ptr]](ptr noundef nonnull align 1 dereferenceable(1) %t) //CHECK-NEXT: ret void //CHECK-NEXT: } struct MaterializedTemporary { void foo(this MaterializedTemporary&&); MaterializedTemporary(); ~MaterializedTemporary(); }; void test_temporary() { MaterializedTemporary{}.foo(); } //CHECK: define dso_local void @_Z14test_temporaryv(){{.*}} //CHECK-NEXT: entry: //CHECK: %ref.tmp = alloca %struct.MaterializedTemporary, align 1 //CHECK: call void @_ZN21MaterializedTemporaryC1Ev(ptr noundef nonnull align 1 dereferenceable(1) %ref.tmp){{.*}} //CHECK invoke void @_ZNH21MaterializedTemporary3fooEOS_(ptr noundef nonnull align 1 dereferenceable(1) %ref.tmp){{.*}} namespace GH86399 { volatile int a = 0; struct function { function& operator=(function const&) { a = 1; return *this; } }; void f() { function list; //CHECK-LABEL: define internal void @"_ZZN7GH863991f{{.*}}"(ptr %{{.*}}) //CHECK: call {{.*}} @_ZN7GH863998functionaSERKS0_ //CHECK-NEXT: ret void [&list](this auto self) { list = function{}; }(); } } namespace GH84163 { // Just check that this doesn't crash (we were previously not instantiating // everything that needs instantiating in here). template struct S {}; void a() { int x; const auto l = [&x](this auto&) { S q; }; l(); } } namespace GH84425 { // As above. void do_thing(int x) { auto second = [&](this auto const& self, int b) -> int { if (x) return x; else return self(x); }; second(1); } void do_thing2(int x) { auto second = [&](this auto const& self) { if (true) return x; else return x; }; second(); } } namespace GH79754 { // As above. void f() { int x; [&x](this auto&&) {return x;}(); } } namespace GH70604 { auto dothing(int num) { auto fun = [&num](this auto&& self) -> void { auto copy = num; }; fun(); } }