237 lines · cpp
1// RUN: %clang_cc1 -std=c++11 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s2// RUN: %clang_cc1 -std=c++20 -triple i386-unknown-unknown %s -emit-llvm -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECKCXX203// RUN: %clang_cc1 -std=c++11 -triple i386-unknown-unknown %s -emit-llvm -fsanitize=signed-integer-overflow -o - | FileCheck --check-prefix=SIO %s4 5// CHECK: @[[ABC4:.*]] = {{.*}} constant [4 x i8] c"abc\00"6// CHECK: @[[ABC15:.*]] = {{.*}} constant [15 x i8] c"abc\00\00\00\007 8// CHECK-LABEL: define{{.*}} void @_Z2fni9void fn(int n) {10 // CHECK: icmp ult i{{32|64}} %{{[^ ]+}}, 311 // CHECK: store i32 112 // CHECK: store i32 213 // CHECK: store i32 314 // CHECK: sub {{.*}}, 1215 // CHECK: call void @llvm.memset16 new int[n] { 1, 2, 3 };17}18 19#if __cplusplus >= 202002L20// CHECKCXX20-LABEL: define{{.*}} void @_Z8fn_pareni21void fn_paren(int n) {22 // CHECKCXX20: icmp ult i{{32|64}} %{{[^ ]+}}, 323 // CHECKCXX20: store i32 124 // CHECKCXX20: store i32 225 // CHECKCXX20: store i32 326 // CHECKCXX20: sub {{.*}}, 1227 // CHECKCXX20: call void @llvm.memset28 new int[n](1, 2, 3);29}30#endif31 32// CHECK-LABEL: define{{.*}} void @_Z11const_exactv33void const_exact() {34 // CHECK-NOT: icmp ult i{{32|64}} %{{[^ ]+}}, 335 // CHECK-NOT: icmp eq ptr36 new int[3] { 1, 2, 3 };37}38 39#if __cplusplus >= 202002L40// CHECKCXX20-LABEL: define{{.*}} void @_Z17const_exact_parenv41void const_exact_paren() {42 // CHECKCXX20-NOT: icmp ult i{{32|64}} %{{[^ ]+}}, 343 // CHECKCXX20-NOT: icmp eq ptr44 new int[3](1, 2, 3);45}46#endif47 48// CHECK-LABEL: define{{.*}} void @_Z16const_sufficientv49void const_sufficient() {50 // CHECK-NOT: icmp ult i{{32|64}} %{{[^ ]+}}, 351 new int[4] { 1, 2, 3 };52 // CHECK: ret void53}54 55#if __cplusplus >= 202002L56// CHECKCXX20-LABEL: define{{.*}} void @_Z22const_sufficient_parenv57void const_sufficient_paren() {58 // CHECKCXX20-NOT: icmp ult i{{32|64}} %{{[^ ]+}}, 359 new int[4](1, 2, 3);60 // CHECKCXX20: ret void61}62#endif63 64// CHECK-LABEL: define{{.*}} void @_Z22check_array_value_initv65void check_array_value_init() {66 struct S;67 new (int S::*[3][4][5]) ();68 69 // CHECK: call noalias noundef nonnull ptr @_Zna{{.}}(i{{32 noundef 240|64 noundef 480}})70 // CHECK: getelementptr inbounds i{{32|64}}, ptr {{.*}}, i{{32|64}} 6071 72 // CHECK: phi73 // CHECK: store i{{32|64}} -1,74 // CHECK: getelementptr inbounds i{{32|64}}, ptr {{.*}}, i{{32|64}} 175 // CHECK: icmp eq76 // CHECK: br i177}78 79// CHECK-LABEL: define{{.*}} void @_Z15string_nonconsti80void string_nonconst(int n) {81 // CHECK: icmp {{s|u}}lt i{{32|64}} %{{[^ ]+}}, 482 // FIXME: Conditionally throw an exception rather than passing -1 to alloc function83 // CHECK: select84 // CHECK: %[[PTR:.*]] = call noalias noundef nonnull ptr @_Zna{{.}}(i{{32|64}}85 // CHECK: call void @llvm.memcpy{{.*}}(ptr align {{[0-9]+}} %[[PTR]], ptr align {{[0-9]+}} @[[ABC4]], i32 4,86 // CHECK: %[[REST:.*]] = getelementptr inbounds i8, ptr %[[PTR]], i32 487 // CHECK: %[[RESTSIZE:.*]] = sub {{.*}}, 488 // CHECK: call void @llvm.memset{{.*}}(ptr align {{[0-9]+}} %[[REST]], i8 0, i{{32|64}} %[[RESTSIZE]],89 new char[n] { "abc" };90}91 92#if __cplusplus >= 202002L93// CHECKCXX20-LABEL: define{{.*}} void @_Z21string_nonconst_pareni94void string_nonconst_paren(int n) {95 // CHECKCXX20: icmp {{s|u}}lt i{{32|64}} %{{[^ ]+}}, 496 // FIXME: Conditionally throw an exception rather than passing -1 to alloc function97 // CHECKCXX20: select98 // CHECKCXX20: %[[PTR:.*]] = call noalias noundef nonnull ptr @_Zna{{.}}(i{{32|64}}99 // CHECKCXX20: call void @llvm.memcpy{{.*}}(ptr align {{[0-9]+}} %[[PTR]], ptr align {{[0-9]+}} @[[ABC4]], i32 4,100 // CHECKCXX20: %[[REST:.*]] = getelementptr inbounds i8, ptr %[[PTR]], i32 4101 // CHECKCXX20: %[[RESTSIZE:.*]] = sub {{.*}}, 4102 // CHECKCXX20: call void @llvm.memset{{.*}}(ptr align {{[0-9]+}} %[[REST]], i8 0, i{{32|64}} %[[RESTSIZE]],103 new char[n]("abc");104}105 106// CHECKCXX20-LABEL: define{{.*}} void @_Z33string_nonconst_paren_extra_pareni107void string_nonconst_paren_extra_paren(int n) {108 // CHECKCXX20: icmp {{s|u}}lt i{{32|64}} %{{[^ ]+}}, 4109 // FIXME: Conditionally throw an exception rather than passing -1 to alloc function110 // CHECKCXX20: select111 // CHECKCXX20: %[[PTR:.*]] = call noalias noundef nonnull ptr @_Zna{{.}}(i{{32|64}}112 // CHECKCXX20: call void @llvm.memcpy{{.*}}(ptr align {{[0-9]+}} %[[PTR]], ptr align {{[0-9]+}} @[[ABC4]], i32 4,113 // CHECKCXX20: %[[REST:.*]] = getelementptr inbounds i8, ptr %[[PTR]], i32 4114 // CHECKCXX20: %[[RESTSIZE:.*]] = sub {{.*}}, 4115 // CHECKCXX20: call void @llvm.memset{{.*}}(ptr align {{[0-9]+}} %[[REST]], i8 0, i{{32|64}} %[[RESTSIZE]],116 new char[n](("abc"));117}118#endif119 120// CHECK-LABEL: define{{.*}} void @_Z12string_exactv121void string_exact() {122 // CHECK-NOT: icmp123 // CHECK: %[[PTR:.*]] = call noalias noundef nonnull ptr @_Zna{{.}}(i{{32|64}} noundef 4)124 // CHECK: call void @llvm.memcpy{{.*}}(ptr align {{[0-9]+}} %[[PTR]], ptr align {{[0-9]+}} @[[ABC4]], i32 4,125 // CHECK-NOT: memset126 new char[4] { "abc" };127}128 129#if __cplusplus >= 202002L130// CHECKCXX20-LABEL: define{{.*}} void @_Z18string_exact_parenv131void string_exact_paren() {132 // CHECKCXX20-NOT: icmp133 // CHECKCXX20: %[[PTR:.*]] = call noalias noundef nonnull ptr @_Zna{{.}}(i{{32|64}} noundef 4)134 // CHECKCXX20: call void @llvm.memcpy{{.*}}(ptr align {{[0-9]+}} %[[PTR]], ptr align {{[0-9]+}} @[[ABC4]], i32 4,135 // CHECKCXX20-NOT: memset136 new char[4]("abc");137}138 139// CHECKCXX20-LABEL: define{{.*}} void @_Z28string_exact_paren_extensionv140void string_exact_paren_extension() {141 // CHECKCXX20-NOT: icmp142 // CHECKCXX20: %[[PTR:.*]] = call noalias noundef nonnull ptr @_Zna{{.}}(i{{32|64}} noundef 4)143 // CHECKCXX20: call void @llvm.memcpy{{.*}}(ptr align {{[0-9]+}} %[[PTR]], ptr align {{[0-9]+}} @[[ABC4]], i32 4,144 // CHECKCXX20-NOT: memset145 new char[4](__extension__ "abc");146}147#endif148 149// CHECK-LABEL: define{{.*}} void @_Z17string_sufficientv150void string_sufficient() {151 // CHECK-NOT: icmp152 // CHECK: %[[PTR:.*]] = call noalias noundef nonnull ptr @_Zna{{.}}(i{{32|64}} noundef 15)153 // FIXME: For very large arrays, it would be preferable to emit a small copy and a memset.154 // CHECK: call void @llvm.memcpy{{.*}}(ptr align {{[0-9]+}} %[[PTR]], ptr align {{[0-9]+}} @[[ABC15]], i32 15,155 // CHECK-NOT: memset156 new char[15] { "abc" };157}158 159#if __cplusplus >= 202002L160// CHECKCXX20-LABEL: define{{.*}} void @_Z23string_sufficient_parenv161void string_sufficient_paren() {162 // CHECKCXX20-NOT: icmp163 // CHECKCXX20: %[[PTR:.*]] = call noalias noundef nonnull ptr @_Zna{{.}}(i{{32|64}} noundef 15)164 // FIXME: For very large arrays, it would be preferable to emit a small copy and a memset.165 // CHECKCXX20: call void @llvm.memcpy{{.*}}(ptr align {{[0-9]+}} %[[PTR]], ptr align {{[0-9]+}} @[[ABC15]], i32 15,166 // CHECKCXX20-NOT: memset167 new char[15]("abc");168}169#endif170 171// CHECK-LABEL: define{{.*}} void @_Z10aggr_exactv172void aggr_exact() {173 // CHECK-NOT: icmp174 // CHECK: %[[MEM:.*]] = call noalias noundef nonnull ptr @_Zna{{.}}(i{{32|64}} noundef 16)175 // CHECK: %[[FIELD:.*]] = getelementptr inbounds nuw %[[AGGR:.*]], ptr %[[MEM]], i32 0, i32 0{{$}}176 // CHECK: store i32 1, ptr %[[FIELD]]177 // CHECK: %[[FIELD:.*]] = getelementptr inbounds nuw %[[AGGR]], ptr %[[MEM]], i32 0, i32 1{{$}}178 // CHECK: store i32 2, ptr %[[FIELD]]179 // CHECK: %[[PTR1:.*]] = getelementptr inbounds %[[AGGR]], ptr %[[MEM]], i32 1{{$}}180 // CHECK: %[[FIELD:.*]] = getelementptr inbounds nuw %[[AGGR]], ptr %[[PTR1]], i32 0, i32 0{{$}}181 // CHECK: store i32 3, ptr %[[FIELD]]182 // CHECK: %[[FIELD:.*]] = getelementptr inbounds nuw %[[AGGR]], ptr %[[PTR1]], i32 0, i32 1{{$}}183 // CHECK: store i32 0, ptr %[[FIELD]]184 // CHECK-NOT: store185 // CHECK-NOT: memset186 struct Aggr { int a, b; };187 new Aggr[2] { 1, 2, 3 };188}189 190// CHECK-LABEL: define{{.*}} void @_Z15aggr_sufficienti191void aggr_sufficient(int n) {192 // CHECK: icmp ult i32 %{{.*}}, 2193 // CHECK: %[[MEM:.*]] = call noalias noundef nonnull ptr @_Zna{{.}}(194 // CHECK: %[[FIELD:.*]] = getelementptr inbounds nuw %[[AGGR:.*]], ptr %[[MEM]], i32 0, i32 0{{$}}195 // CHECK: store i32 1, ptr %[[FIELD]]196 // CHECK: %[[FIELD:.*]] = getelementptr inbounds nuw %[[AGGR]], ptr %[[MEM]], i32 0, i32 1{{$}}197 // CHECK: store i32 2, ptr %[[FIELD]]198 // CHECK: %[[PTR1:.*]] = getelementptr inbounds %[[AGGR]], ptr %[[MEM]], i32 1{{$}}199 // CHECK: %[[FIELD:.*]] = getelementptr inbounds nuw %[[AGGR]], ptr %[[PTR1]], i32 0, i32 0{{$}}200 // CHECK: store i32 3, ptr %[[FIELD]]201 // CHECK: %[[FIELD:.*]] = getelementptr inbounds nuw %[[AGGR]], ptr %[[PTR1]], i32 0, i32 1{{$}}202 // CHECK: store i32 0, ptr %[[FIELD]]203 // CHECK: %[[PTR2:.*]] = getelementptr inbounds %[[AGGR]], ptr %[[PTR1]], i32 1{{$}}204 // CHECK: %[[REMAIN:.*]] = sub i32 {{.*}}, 16205 // CHECK: call void @llvm.memset{{.*}}(ptr align {{[0-9]+}} %[[PTR2]], i8 0, i32 %[[REMAIN]],206 struct Aggr { int a, b; };207 new Aggr[n] { 1, 2, 3 };208}209 210// SIO-LABEL: define{{.*}} void @_Z14constexpr_testv211void constexpr_test() {212 // SIO: call noalias noundef nonnull ptr @_Zna{{.}}(i32 noundef 4)213 new int[0+1]{0};214}215 216// CHECK-LABEL: define{{.*}} void @_Z13unknown_boundv217void unknown_bound() {218 struct Aggr { int x, y, z; };219 new Aggr[]{1, 2, 3, 4};220 // CHECK: call {{.*}}_Znaj(i32 noundef 24)221 // CHECK: store i32 1222 // CHECK: store i32 2223 // CHECK: store i32 3224 // CHECK: store i32 4225 // CHECK: store i32 0226 // CHECK: store i32 0227 // CHECK-NOT: store228 // CHECK: }229}230 231// CHECK-LABEL: define{{.*}} void @_Z20unknown_bound_stringv232void unknown_bound_string() {233 new char[]{"hello"};234 // CHECK: call {{.*}}_Znaj(i32 noundef 6)235 // CHECK: memcpy{{.*}} i32 6,236}237