brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.2 KiB · 2d09732 Raw
372 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=NEWABI2// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown -fclang-abi-compat=4.0 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=OLDABI3// RUN: %clang_cc1 -std=c++11 -triple x86_64-scei-ps4 -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=OLDABI4// RUN: %clang_cc1 -std=c++11 -triple x86_64-sie-ps5  -emit-llvm -o - %s | FileCheck %s --check-prefix=CHECK --check-prefix=NEWABI5// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm -o - %s -fms-compatibility -fms-compatibility-version=18 | FileCheck %s -check-prefix=WIN64 -check-prefix=WIN64-186// RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm -o - %s -fms-compatibility -fms-compatibility-version=19 | FileCheck %s -check-prefix=WIN64 -check-prefix=WIN64-197 8namespace trivial {9// Trivial structs should be passed directly.10struct A {11  void *p;12};13void foo(A);14void bar() {15  foo({});16}17// CHECK-LABEL: define{{.*}} void @_ZN7trivial3barEv()18// CHECK: alloca %"struct.trivial::A"19// CHECK: load ptr, ptr20// CHECK: call void @_ZN7trivial3fooENS_1AE(ptr %{{.*}})21// CHECK-LABEL: declare void @_ZN7trivial3fooENS_1AE(ptr)22 23// WIN64-LABEL: declare dso_local void @"?foo@trivial@@YAXUA@1@@Z"(i64)24}25 26namespace default_ctor {27struct A {28  A();29  void *p;30};31void foo(A);32void bar() {33  // Core issue 1590.  We can pass this type in registers, even though C++34  // normally doesn't permit copies when using braced initialization.35  foo({});36}37// CHECK-LABEL: define{{.*}} void @_ZN12default_ctor3barEv()38// CHECK: alloca %"struct.default_ctor::A"39// CHECK: call void @_Z{{.*}}C1Ev(40// CHECK: load ptr, ptr41// CHECK: call void @_ZN12default_ctor3fooENS_1AE(ptr %{{.*}})42// CHECK-LABEL: declare void @_ZN12default_ctor3fooENS_1AE(ptr)43 44// WIN64-LABEL: declare dso_local void @"?foo@default_ctor@@YAXUA@1@@Z"(i64)45}46 47namespace move_ctor {48// The presence of a move constructor implicitly deletes the trivial copy ctor49// and means that we have to pass this struct by address.50struct A {51  A();52  A(A &&o);53  void *p;54};55void foo(A);56void bar() {57  foo({});58}59// CHECK-LABEL: define{{.*}} void @_ZN9move_ctor3barEv()60// CHECK: call void @_Z{{.*}}C1Ev(61// CHECK-NOT: call62// NEWABI: call void @_ZN9move_ctor3fooENS_1AE(ptr dead_on_return noundef %{{.*}})63// OLDABI: call void @_ZN9move_ctor3fooENS_1AE(ptr %{{.*}})64// NEWABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(ptr dead_on_return noundef)65// OLDABI-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(ptr)66 67// WIN64-LABEL: declare dso_local void @"?foo@move_ctor@@YAXUA@1@@Z"(ptr dead_on_return noundef)68}69 70namespace all_deleted {71struct A {72  A();73  A(const A &o) = delete;74  A(A &&o) = delete;75  void *p;76};77void foo(A);78void bar() {79  foo({});80}81// CHECK-LABEL: define{{.*}} void @_ZN11all_deleted3barEv()82// CHECK: call void @_Z{{.*}}C1Ev(83// CHECK-NOT: call84// NEWABI: call void @_ZN11all_deleted3fooENS_1AE(ptr dead_on_return noundef %{{.*}})85// OLDABI: call void @_ZN11all_deleted3fooENS_1AE(ptr %{{.*}})86// NEWABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(ptr dead_on_return noundef)87// OLDABI-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(ptr)88 89// WIN64-LABEL: declare dso_local void @"?foo@all_deleted@@YAXUA@1@@Z"(ptr dead_on_return noundef)90}91 92namespace implicitly_deleted {93struct A {94  A();95  A &operator=(A &&o);96  void *p;97};98void foo(A);99void bar() {100  foo({});101}102// CHECK-LABEL: define{{.*}} void @_ZN18implicitly_deleted3barEv()103// CHECK: call void @_Z{{.*}}C1Ev(104// CHECK-NOT: call105// NEWABI: call void @_ZN18implicitly_deleted3fooENS_1AE(ptr dead_on_return noundef %{{.*}})106// OLDABI: call void @_ZN18implicitly_deleted3fooENS_1AE(ptr %{{.*}})107// NEWABI-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(ptr dead_on_return noundef)108// OLDABI-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(ptr)109 110// In MSVC 2013, the copy ctor is not deleted by a move assignment. In MSVC 2015, it is.111// WIN64-18-LABEL: declare dso_local void @"?foo@implicitly_deleted@@YAXUA@1@@Z"(i64112// WIN64-19-LABEL: declare dso_local void @"?foo@implicitly_deleted@@YAXUA@1@@Z"(ptr dead_on_return noundef)113}114 115namespace one_deleted {116struct A {117  A();118  A(A &&o) = delete;119  void *p;120};121void foo(A);122void bar() {123  foo({});124}125// CHECK-LABEL: define{{.*}} void @_ZN11one_deleted3barEv()126// CHECK: call void @_Z{{.*}}C1Ev(127// CHECK-NOT: call128// NEWABI: call void @_ZN11one_deleted3fooENS_1AE(ptr dead_on_return noundef %{{.*}})129// OLDABI: call void @_ZN11one_deleted3fooENS_1AE(ptr %{{.*}})130// NEWABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(ptr dead_on_return noundef)131// OLDABI-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(ptr)132 133// WIN64-LABEL: declare dso_local void @"?foo@one_deleted@@YAXUA@1@@Z"(ptr dead_on_return noundef)134}135 136namespace copy_defaulted {137struct A {138  A();139  A(const A &o) = default;140  A(A &&o) = delete;141  void *p;142};143void foo(A);144void bar() {145  foo({});146}147// CHECK-LABEL: define{{.*}} void @_ZN14copy_defaulted3barEv()148// CHECK: call void @_Z{{.*}}C1Ev(149// CHECK: load ptr, ptr150// CHECK: call void @_ZN14copy_defaulted3fooENS_1AE(ptr %{{.*}})151// CHECK-LABEL: declare void @_ZN14copy_defaulted3fooENS_1AE(ptr)152 153// WIN64-LABEL: declare dso_local void @"?foo@copy_defaulted@@YAXUA@1@@Z"(i64)154}155 156namespace move_defaulted {157struct A {158  A();159  A(const A &o) = delete;160  A(A &&o) = default;161  void *p;162};163void foo(A);164void bar() {165  foo({});166}167// CHECK-LABEL: define{{.*}} void @_ZN14move_defaulted3barEv()168// CHECK: call void @_Z{{.*}}C1Ev(169// CHECK: load ptr, ptr170// CHECK: call void @_ZN14move_defaulted3fooENS_1AE(ptr %{{.*}})171// CHECK-LABEL: declare void @_ZN14move_defaulted3fooENS_1AE(ptr)172 173// WIN64-LABEL: declare dso_local void @"?foo@move_defaulted@@YAXUA@1@@Z"(ptr dead_on_return noundef)174}175 176namespace trivial_defaulted {177struct A {178  A();179  A(const A &o) = default;180  void *p;181};182void foo(A);183void bar() {184  foo({});185}186// CHECK-LABEL: define{{.*}} void @_ZN17trivial_defaulted3barEv()187// CHECK: call void @_Z{{.*}}C1Ev(188// CHECK: load ptr, ptr189// CHECK: call void @_ZN17trivial_defaulted3fooENS_1AE(ptr %{{.*}})190// CHECK-LABEL: declare void @_ZN17trivial_defaulted3fooENS_1AE(ptr)191 192// WIN64-LABEL: declare dso_local void @"?foo@trivial_defaulted@@YAXUA@1@@Z"(i64)193}194 195namespace two_copy_ctors {196struct A {197  A();198  A(const A &) = default;199  A(const A &, int = 0);200  void *p;201};202struct B : A {};203 204void foo(B);205void bar() {206  foo({});207}208// CHECK-LABEL: define{{.*}} void @_ZN14two_copy_ctors3barEv()209// CHECK: call void @_Z{{.*}}C1Ev(210// NEWABI: call void @_ZN14two_copy_ctors3fooENS_1BE(ptr dead_on_return noundef %{{.*}})211// OLDABI: call void @_ZN14two_copy_ctors3fooENS_1BE(ptr noundef byval212// NEWABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(ptr dead_on_return noundef)213// OLDABI-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(ptr noundef byval214 215// WIN64-LABEL: declare dso_local void @"?foo@two_copy_ctors@@YAXUB@1@@Z"(ptr dead_on_return noundef)216}217 218namespace definition_only {219struct A {220  A();221  A(A &&o);222  void *p;223};224void *foo(A a) { return a.p; }225// NEWABI-LABEL: define{{.*}} ptr @_ZN15definition_only3fooENS_1AE(ptr226// OLDABI-LABEL: define{{.*}} ptr @_ZN15definition_only3fooENS_1AE(ptr227// WIN64-LABEL: define dso_local noundef ptr @"?foo@definition_only@@YAPEAXUA@1@@Z"(ptr228}229 230namespace deleted_by_member {231struct B {232  B();233  B(B &&o);234  void *p;235};236struct A {237  A();238  B b;239};240void *foo(A a) { return a.b.p; }241// NEWABI-LABEL: define{{.*}} ptr @_ZN17deleted_by_member3fooENS_1AE(ptr242// OLDABI-LABEL: define{{.*}} ptr @_ZN17deleted_by_member3fooENS_1AE(ptr243// WIN64-LABEL: define dso_local noundef ptr @"?foo@deleted_by_member@@YAPEAXUA@1@@Z"(ptr244}245 246namespace deleted_by_base {247struct B {248  B();249  B(B &&o);250  void *p;251};252struct A : B {253  A();254};255void *foo(A a) { return a.p; }256// NEWABI-LABEL: define{{.*}} ptr @_ZN15deleted_by_base3fooENS_1AE(ptr257// OLDABI-LABEL: define{{.*}} ptr @_ZN15deleted_by_base3fooENS_1AE(ptr258// WIN64-LABEL: define dso_local noundef ptr @"?foo@deleted_by_base@@YAPEAXUA@1@@Z"(ptr259}260 261namespace deleted_by_member_copy {262struct B {263  B();264  B(const B &o) = delete;265  void *p;266};267struct A {268  A();269  B b;270};271void *foo(A a) { return a.b.p; }272// NEWABI-LABEL: define{{.*}} ptr @_ZN22deleted_by_member_copy3fooENS_1AE(ptr273// OLDABI-LABEL: define{{.*}} ptr @_ZN22deleted_by_member_copy3fooENS_1AE(ptr274// WIN64-LABEL: define dso_local noundef ptr @"?foo@deleted_by_member_copy@@YAPEAXUA@1@@Z"(ptr275}276 277namespace deleted_by_base_copy {278struct B {279  B();280  B(const B &o) = delete;281  void *p;282};283struct A : B {284  A();285};286void *foo(A a) { return a.p; }287// NEWABI-LABEL: define{{.*}} ptr @_ZN20deleted_by_base_copy3fooENS_1AE(ptr288// OLDABI-LABEL: define{{.*}} ptr @_ZN20deleted_by_base_copy3fooENS_1AE(ptr289// WIN64-LABEL: define dso_local noundef ptr @"?foo@deleted_by_base_copy@@YAPEAXUA@1@@Z"(ptr290}291 292namespace explicit_delete {293struct A {294  A();295  A(const A &o) = delete;296  void *p;297};298// NEWABI-LABEL: define{{.*}} ptr @_ZN15explicit_delete3fooENS_1AE(ptr299// OLDABI-LABEL: define{{.*}} ptr @_ZN15explicit_delete3fooENS_1AE(ptr300// WIN64-LABEL: define dso_local noundef ptr @"?foo@explicit_delete@@YAPEAXUA@1@@Z"(ptr301void *foo(A a) { return a.p; }302}303 304namespace implicitly_deleted_copy_ctor {305struct A {306  // No move ctor due to copy assignment.307  A &operator=(const A&);308  // Deleted copy ctor due to rvalue ref member.309  int &&ref;310};311// NEWABI-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1AE(ptr312// OLDABI-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1AE(ptr313// WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAAEAHUA@1@@Z"(ptr314int &foo(A a) { return a.ref; }315 316struct B {317  // Passed direct: has non-deleted trivial copy ctor.318  B &operator=(const B&);319  int &ref;320};321int &foo(B b) { return b.ref; }322// CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1BE(ptr323// WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAAEAHUB@1@@Z"(i64324 325struct X { X(const X&); };326struct Y { Y(const Y&) = default; };327 328union C {329  C &operator=(const C&);330  // Passed indirect: copy ctor deleted due to variant member with nontrivial copy ctor.331  X x;332  int n;333};334int foo(C c) { return c.n; }335// CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1CE(ptr336// WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHTC@1@@Z"(ptr337 338struct D {339  D &operator=(const D&);340  // Passed indirect: copy ctor deleted due to variant member with nontrivial copy ctor.341  union {342    X x;343    int n;344  };345};346int foo(D d) { return d.n; }347// CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1DE(ptr348// WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHUD@1@@Z"(ptr349 350union E {351  // Passed direct: has non-deleted trivial copy ctor.352  E &operator=(const E&);353  Y y;354  int n;355};356int foo(E e) { return e.n; }357// CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1EE(i32358// WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHTE@1@@Z"(i32359 360struct F {361  // Passed direct: has non-deleted trivial copy ctor.362  F &operator=(const F&);363  union {364    Y y;365    int n;366  };367};368int foo(F f) { return f.n; }369// CHECK-LABEL: define {{.*}} @_ZN28implicitly_deleted_copy_ctor3fooENS_1FE(i32370// WIN64-LABEL: define {{.*}} @"?foo@implicitly_deleted_copy_ctor@@YAHUF@1@@Z"(i32371}372