brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.4 KiB · 9664a86 Raw
319 lines · cpp
1// RUN: %clang_cc1 -std=c++2b %s -emit-llvm -triple x86_64-linux -o - | FileCheck %s2 3struct TrivialStruct {4    void explicit_object_function(this TrivialStruct) {}5};6void test() {7    TrivialStruct s;8    s.explicit_object_function();9}10// CHECK:      define {{.*}}test{{.*}}11// CHECK-NEXT: entry:12// CHECK:      {{.*}} = alloca %struct.TrivialStruct, align 113// CHECK:      {{.*}} = alloca %struct.TrivialStruct, align 114// CHECK:      call void {{.*}}explicit_object_function{{.*}}15// CHECK-NEXT: ret void16// CHECK-NEXT: }17 18// CHECK:      define {{.*}}explicit_object_function{{.*}}19// CHECK-NEXT: entry:20// CHECK:        {{.*}} = alloca %struct.TrivialStruct, align 121// CHECK:        ret void22// CHECK-NEXT: }23 24 25void test_lambda() {26    [](this auto This) -> int {27        return This();28    }();29}30 31//CHECK: define dso_local void @{{.*}}test_lambda{{.*}}() #0 {32//CHECK: entry:33//CHECK:  %agg.tmp = alloca %class.anon, align 134//CHECK:  %call = call noundef i32 @"_ZZ11test_lambdavENH3$_0clIS_EEiT_"()35//CHECK:  ret void36//CHECK: }37 38//CHECK: define internal noundef i32 @"_ZZ11test_lambdavENH3$_0clIS_EEiT_"() #0 align 2 {39//CHECK: entry:40//CHECK:   %This = alloca %class.anon, align 141//CHECK:   %agg.tmp = alloca %class.anon, align 142//CHECK:   %call = call noundef i32 @"_ZZ11test_lambdavENH3$_0clIS_EEiT_"()43//CHECK:   ret i32 %call44//CHECK: }45 46void test_lambda_ref() {47    auto l = [i = 42](this auto & This, int j) -> int {48        return This(j);49    };50    l(0);51}52 53// CHECK: define dso_local void @_Z15test_lambda_refv() #0 {54// CHECK: entry:55// CHECK:   %[[This_address:.]] = alloca %class.anon{{.*}}, align 456// CHECK:   %[[i_addr:.*]] = getelementptr inbounds nuw %class.anon{{.*}}, ptr %[[This_address]], i32 0, i32 057// CHECK:   store i32 42, ptr %[[i_addr]], align 458// CHECK:   %call = call noundef i32 @"_ZZ15test_lambda_refvENH3$_0clIS_EEiRT_i"{{.*}}59// CHECK:   ret void60// CHECK: }61 62// CHECK: define internal noundef i32 @"_ZZ15test_lambda_refvENH3$_0clIS_EEiRT_i"{{.*}}63// CHECK: entry:64// CHECK:  %This.addr = alloca ptr, align 865// CHECK:  %j.addr = alloca i32, align 466// CHECK:  store ptr %This, ptr %This.addr, align 867// CHECK:  store i32 %j, ptr %j.addr, align 468// CHECK:  %[[this_addr:.*]] = load ptr, ptr %This.addr, align 869// CHECK:  %[[j_addr:.*]] = load i32, ptr %j.addr, align 470// CHECK:  %call = call noundef i32 @"_ZZ15test_lambda_refvENH3$_0clIS_EEiRT_i"(ptr noundef nonnull align 4 dereferenceable(4) %[[this_addr]], i32 noundef %[[j_addr]])71// CHECK:  ret i32 %call72// CHECK: }73 74 75struct TestPointer {76    void f(this TestPointer &);77};78 79void test_pointer() {80    TestPointer t;81    using Fn = void(TestPointer&);82    Fn* fn = &TestPointer::f;83    fn(t);84}85//CHECK: define dso_local void @_Z12test_pointerv() #0 {86//CHECK-NEXT: entry:87//CHECK-NEXT:  %t = alloca %struct.TestPointer, align 188//CHECK-NEXT:  %fn = alloca ptr, align 889//CHECK-NEXT:  store ptr @_ZNH11TestPointer1fERS_, ptr %fn, align 890//CHECK:       %[[fn_ptr:.*]] = load ptr, ptr %fn, align 891//CHECK-NEXT:  call void %[[fn_ptr]](ptr noundef nonnull align 1 dereferenceable(1) %t)92//CHECK-NEXT:  ret void93//CHECK-NEXT: }94 95 96struct MaterializedTemporary {97  void foo(this MaterializedTemporary&&);98  MaterializedTemporary();99  ~MaterializedTemporary();100};101 102void test_temporary() {103  MaterializedTemporary{}.foo();104}105 106//CHECK: define dso_local void @_Z14test_temporaryv(){{.*}}107//CHECK-NEXT: entry:108//CHECK:    %ref.tmp = alloca %struct.MaterializedTemporary, align 1109//CHECK:    call void @_ZN21MaterializedTemporaryC1Ev(ptr noundef nonnull align 1 dereferenceable(1) %ref.tmp){{.*}}110//CHECK     invoke void @_ZNH21MaterializedTemporary3fooEOS_(ptr noundef nonnull align 1 dereferenceable(1) %ref.tmp){{.*}}111 112namespace GH86399 {113volatile int a = 0;114struct function {115  function& operator=(function const&) {116    a = 1;117    return *this;118  }119};120 121void f() {122  function list;123 124  //CHECK-LABEL: define internal void @"_ZZN7GH863991f{{.*}}"(ptr %{{.*}})125  //CHECK: call {{.*}} @_ZN7GH863998functionaSERKS0_126  //CHECK-NEXT: ret void127  [&list](this auto self) {128    list = function{};129  }();130}131}132 133namespace GH84163 {134// Just check that this doesn't crash (we were previously not instantiating135// everything that needs instantiating in here).136template <typename> struct S {};137 138void a() {139  int x;140  const auto l = [&x](this auto&) { S<decltype(x)> q; };141  l();142}143}144 145namespace GH84425 {146// As above.147void do_thing(int x) {148    auto second = [&](this auto const& self, int b) -> int {149        if (x) return x;150        else return self(x);151    };152 153     second(1);154}155 156void do_thing2(int x) {157    auto second = [&](this auto const& self)  {158        if (true) return x;159        else return x;160    };161 162     second();163}164}165 166namespace GH79754 {167// As above.168void f() {169  int x;170  [&x](this auto&&) {return x;}();171}172}173 174namespace GH70604 {175auto dothing(int num)176{177  auto fun =  [&num](this auto&& self) -> void {178    auto copy = num;179  };180 181  fun();182}183}184 185namespace GH87210 {186template <typename... Ts>187struct Overloaded : Ts... {188  using Ts::operator()...;189};190 191template <typename... Ts>192Overloaded(Ts...) -> Overloaded<Ts...>;193 194// CHECK-LABEL: define dso_local void @_ZN7GH872101fEv()195// CHECK-NEXT:  entry:196// CHECK-NEXT:    [[X:%.*]] = alloca i32197// CHECK-NEXT:    [[Over:%.*]] = alloca %"{{.*}}Overloaded"198// CHECK:         call noundef ptr @"_ZZN7GH872101fEvENH3$_0clINS_10OverloadedIJS0_EEEEEDaRT_"(ptr {{.*}} [[Over]])199void f() {200  int x;201  Overloaded o {202    // CHECK: define internal noundef ptr @"_ZZN7GH872101fEvENH3$_0clINS_10OverloadedIJS0_EEEEEDaRT_"(ptr {{.*}} [[Self:%.*]])203    // CHECK-NEXT:  entry:204    // CHECK-NEXT:    [[SelfAddr:%.*]] = alloca ptr205    // CHECK-NEXT:    store ptr [[Self]], ptr [[SelfAddr]]206    // CHECK-NEXT:    [[SelfPtr:%.*]] = load ptr, ptr [[SelfAddr]]207    // CHECK-NEXT:    [[XRef:%.*]] = getelementptr inbounds nuw %{{.*}}, ptr [[SelfPtr]], i32 0, i32 0208    // CHECK-NEXT:    [[X:%.*]] = load ptr, ptr [[XRef]]209    // CHECK-NEXT:    ret ptr [[X]]210    [&](this auto& self) {211      return &x;212    }213  };214  o();215}216 217void g() {218  int x;219  Overloaded o {220    [=](this auto& self) {221      return x;222    }223  };224  o();225}226}227 228namespace GH89541 {229// Same as above; just check that this doesn't crash.230int one = 1;231auto factory(int& x = one) {232  return [&](this auto self) {233    x;234  };235};236 237using Base = decltype(factory());238struct Derived : Base {239  Derived() : Base(factory()) {}240};241 242void f() {243  Derived d;244  d();245}246}247 248 249namespace P2797 {250struct C {251  void c(this const C&);    // #first252  void c() &;               // #second253  static void c(int = 0);   // #third254 255  void d() {256    (&C::c)(C{});257    (&C::c)();258  }259};260void test() {261    (void)C{}.d();262}263// CHECK-LABEL: {{.*}} @_ZN5P27971C1dEv264// CHECK: call void @_ZNH5P27971C1cERKS0_265// CHECK: call void @_ZN5P27971C1cEi266}267 268// This used to crash because we weren’t instantiating a dependent 'this'.269namespace GH154054 {270struct S {271  int x;272  auto byval() {273    return [*this](this auto) { return this->x; };274  }275};276 277// CHECK-LABEL: define {{.*}} void @_ZN8GH1540544mainEv278void main() {279  S s{ 42 };280 281  // CHECK: call {{.*}} i32 @_ZZN8GH1540541S5byvalEvENHUlT_E_clIS2_EEDaS1_282  if ( s.byval()() != 42)283    __builtin_abort();284}285 286// CHECK-LABEL: define {{.*}} i32 @_ZZN8GH1540541S5byvalEvENHUlT_E_clIS2_EEDaS1_(i32 %.coerce)287// CHECK: entry:288// CHECK:   %0 = alloca %class.anon.11, align 4289// CHECK:   %coerce.dive = getelementptr inbounds nuw %class.anon.11, ptr %0, i32 0, i32 0290// CHECK:   %coerce.dive1 = getelementptr inbounds nuw %"struct.GH154054::S", ptr %coerce.dive, i32 0, i32 0291// CHECK:   store i32 %.coerce, ptr %coerce.dive1, align 4292// CHECK:   %1 = getelementptr inbounds nuw %class.anon.11, ptr %0, i32 0, i32 0293// CHECK:   %x = getelementptr inbounds nuw %"struct.GH154054::S", ptr %1, i32 0, i32 0294// CHECK:   %2 = load i32, ptr %x, align 4295// CHECK:   ret i32 %2296 297struct s {298  int q;299  auto f() {300    return [*this](this auto) { return this; };301  }302};303 304// CHECK-LABEL: define {{.*}} void @_ZN8GH1540541fEv305void f() {306  // CHECK: call {{.*}} ptr @_ZZN8GH1540541s1fEvENHUlT_E_clIS2_EEDaS1_307  s{}.f()();308}309 310// CHECK-LABEL: define {{.*}} ptr @_ZZN8GH1540541s1fEvENHUlT_E_clIS2_EEDaS1_(i32 %.coerce)311// CHECK: entry:312// CHECK:   %0 = alloca %class.anon.12, align 4313// CHECK:   %coerce.dive = getelementptr inbounds nuw %class.anon.12, ptr %0, i32 0, i32 0314// CHECK:   %coerce.dive1 = getelementptr inbounds nuw %"struct.GH154054::s", ptr %coerce.dive, i32 0, i32 0315// CHECK:   store i32 %.coerce, ptr %coerce.dive1, align 4316// CHECK:   %1 = getelementptr inbounds nuw %class.anon.12, ptr %0, i32 0, i32 0317// CHECK:   ret ptr %1318}319