Home | History | Annotate | Download | only in CodeGenCXX
      1 // RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
      2 // RUN: %clang_cc1 -std=c++11 -triple x86_64-windows-msvc -emit-llvm -o - %s | FileCheck %s -check-prefix=WIN64
      3 
      4 namespace trivial {
      5 // Trivial structs should be passed directly.
      6 struct A {
      7   void *p;
      8 };
      9 void foo(A);
     10 void bar() {
     11   foo({});
     12 }
     13 // CHECK-LABEL: define void @_ZN7trivial3barEv()
     14 // CHECK: alloca %"struct.trivial::A"
     15 // CHECK: load i8*, i8**
     16 // CHECK: call void @_ZN7trivial3fooENS_1AE(i8* %{{.*}})
     17 // CHECK-LABEL: declare void @_ZN7trivial3fooENS_1AE(i8*)
     18 
     19 // WIN64-LABEL: declare void @"\01?foo@trivial@@YAXUA@1@@Z"(i64)
     20 }
     21 
     22 namespace default_ctor {
     23 struct A {
     24   A();
     25   void *p;
     26 };
     27 void foo(A);
     28 void bar() {
     29   // Core issue 1590.  We can pass this type in registers, even though C++
     30   // normally doesn't permit copies when using braced initialization.
     31   foo({});
     32 }
     33 // CHECK-LABEL: define void @_ZN12default_ctor3barEv()
     34 // CHECK: alloca %"struct.default_ctor::A"
     35 // CHECK: call void @_Z{{.*}}C1Ev(
     36 // CHECK: load i8*, i8**
     37 // CHECK: call void @_ZN12default_ctor3fooENS_1AE(i8* %{{.*}})
     38 // CHECK-LABEL: declare void @_ZN12default_ctor3fooENS_1AE(i8*)
     39 
     40 // WIN64-LABEL: declare void @"\01?foo@default_ctor@@YAXUA@1@@Z"(i64)
     41 }
     42 
     43 namespace move_ctor {
     44 // The presence of a move constructor implicitly deletes the trivial copy ctor
     45 // and means that we have to pass this struct by address.
     46 struct A {
     47   A();
     48   A(A &&o);
     49   void *p;
     50 };
     51 void foo(A);
     52 void bar() {
     53   foo({});
     54 }
     55 // FIXME: The copy ctor is implicitly deleted.
     56 // CHECK-DISABLED-LABEL: define void @_ZN9move_ctor3barEv()
     57 // CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
     58 // CHECK-DISABLED-NOT: call
     59 // CHECK-DISABLED: call void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"* %{{.*}})
     60 // CHECK-DISABLED-LABEL: declare void @_ZN9move_ctor3fooENS_1AE(%"struct.move_ctor::A"*)
     61 
     62 // WIN64-LABEL: declare void @"\01?foo@move_ctor@@YAXUA@1@@Z"(%"struct.move_ctor::A"*)
     63 }
     64 
     65 namespace all_deleted {
     66 struct A {
     67   A();
     68   A(const A &o) = delete;
     69   A(A &&o) = delete;
     70   void *p;
     71 };
     72 void foo(A);
     73 void bar() {
     74   foo({});
     75 }
     76 // FIXME: The copy ctor is deleted.
     77 // CHECK-DISABLED-LABEL: define void @_ZN11all_deleted3barEv()
     78 // CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
     79 // CHECK-DISABLED-NOT: call
     80 // CHECK-DISABLED: call void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"* %{{.*}})
     81 // CHECK-DISABLED-LABEL: declare void @_ZN11all_deleted3fooENS_1AE(%"struct.all_deleted::A"*)
     82 
     83 // WIN64-LABEL: declare void @"\01?foo@all_deleted@@YAXUA@1@@Z"(%"struct.all_deleted::A"*)
     84 }
     85 
     86 namespace implicitly_deleted {
     87 struct A {
     88   A();
     89   A &operator=(A &&o);
     90   void *p;
     91 };
     92 void foo(A);
     93 void bar() {
     94   foo({});
     95 }
     96 // FIXME: The copy and move ctors are implicitly deleted.
     97 // CHECK-DISABLED-LABEL: define void @_ZN18implicitly_deleted3barEv()
     98 // CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
     99 // CHECK-DISABLED-NOT: call
    100 // CHECK-DISABLED: call void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"* %{{.*}})
    101 // CHECK-DISABLED-LABEL: declare void @_ZN18implicitly_deleted3fooENS_1AE(%"struct.implicitly_deleted::A"*)
    102 
    103 // WIN64-LABEL: declare void @"\01?foo@implicitly_deleted@@YAXUA@1@@Z"(%"struct.implicitly_deleted::A"*)
    104 }
    105 
    106 namespace one_deleted {
    107 struct A {
    108   A();
    109   A(A &&o) = delete;
    110   void *p;
    111 };
    112 void foo(A);
    113 void bar() {
    114   foo({});
    115 }
    116 // FIXME: The copy constructor is implicitly deleted.
    117 // CHECK-DISABLED-LABEL: define void @_ZN11one_deleted3barEv()
    118 // CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
    119 // CHECK-DISABLED-NOT: call
    120 // CHECK-DISABLED: call void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"* %{{.*}})
    121 // CHECK-DISABLED-LABEL: declare void @_ZN11one_deleted3fooENS_1AE(%"struct.one_deleted::A"*)
    122 
    123 // WIN64-LABEL: declare void @"\01?foo@one_deleted@@YAXUA@1@@Z"(%"struct.one_deleted::A"*)
    124 }
    125 
    126 namespace copy_defaulted {
    127 struct A {
    128   A();
    129   A(const A &o) = default;
    130   A(A &&o) = delete;
    131   void *p;
    132 };
    133 void foo(A);
    134 void bar() {
    135   foo({});
    136 }
    137 // CHECK-LABEL: define void @_ZN14copy_defaulted3barEv()
    138 // CHECK: call void @_Z{{.*}}C1Ev(
    139 // CHECK: load i8*, i8**
    140 // CHECK: call void @_ZN14copy_defaulted3fooENS_1AE(i8* %{{.*}})
    141 // CHECK-LABEL: declare void @_ZN14copy_defaulted3fooENS_1AE(i8*)
    142 
    143 // WIN64-LABEL: declare void @"\01?foo@copy_defaulted@@YAXUA@1@@Z"(i64)
    144 }
    145 
    146 namespace move_defaulted {
    147 struct A {
    148   A();
    149   A(const A &o) = delete;
    150   A(A &&o) = default;
    151   void *p;
    152 };
    153 void foo(A);
    154 void bar() {
    155   foo({});
    156 }
    157 // CHECK-LABEL: define void @_ZN14move_defaulted3barEv()
    158 // CHECK: call void @_Z{{.*}}C1Ev(
    159 // CHECK: load i8*, i8**
    160 // CHECK: call void @_ZN14move_defaulted3fooENS_1AE(i8* %{{.*}})
    161 // CHECK-LABEL: declare void @_ZN14move_defaulted3fooENS_1AE(i8*)
    162 
    163 // WIN64-LABEL: declare void @"\01?foo@move_defaulted@@YAXUA@1@@Z"(%"struct.move_defaulted::A"*)
    164 }
    165 
    166 namespace trivial_defaulted {
    167 struct A {
    168   A();
    169   A(const A &o) = default;
    170   void *p;
    171 };
    172 void foo(A);
    173 void bar() {
    174   foo({});
    175 }
    176 // CHECK-LABEL: define void @_ZN17trivial_defaulted3barEv()
    177 // CHECK: call void @_Z{{.*}}C1Ev(
    178 // CHECK: load i8*, i8**
    179 // CHECK: call void @_ZN17trivial_defaulted3fooENS_1AE(i8* %{{.*}})
    180 // CHECK-LABEL: declare void @_ZN17trivial_defaulted3fooENS_1AE(i8*)
    181 
    182 // WIN64-LABEL: declare void @"\01?foo@trivial_defaulted@@YAXUA@1@@Z"(i64)
    183 }
    184 
    185 namespace two_copy_ctors {
    186 struct A {
    187   A();
    188   A(const A &) = default;
    189   A(const A &, int = 0);
    190   void *p;
    191 };
    192 struct B : A {};
    193 
    194 void foo(B);
    195 void bar() {
    196   foo({});
    197 }
    198 // FIXME: This class has a non-trivial copy ctor and a trivial copy ctor.  It's
    199 // not clear whether we should pass by address or in registers.
    200 // CHECK-DISABLED-LABEL: define void @_ZN14two_copy_ctors3barEv()
    201 // CHECK-DISABLED: call void @_Z{{.*}}C1Ev(
    202 // CHECK-DISABLED: call void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"* %{{.*}})
    203 // CHECK-DISABLED-LABEL: declare void @_ZN14two_copy_ctors3fooENS_1BE(%"struct.two_copy_ctors::B"*)
    204 
    205 // WIN64-LABEL: declare void @"\01?foo@two_copy_ctors@@YAXUB@1@@Z"(%"struct.two_copy_ctors::B"*)
    206 }
    207