brintos

brintos / llvm-project-archived public Read only

0
0
Text · 11.2 KiB · af22552 Raw
376 lines · cpp
1// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -emit-llvm -o - | FileCheck %s2 3typedef __typeof__(sizeof(0)) size_t;4 5// Declare an 'operator new' template to tickle a bug in __builtin_operator_new.6template<typename T> void *operator new(size_t, int (*)(T));7 8// Ensure that this declaration doesn't cause operator new to lose its9// 'noalias' attribute.10void *operator new[](size_t);11 12void t1() {13  delete new int;14  delete [] new int [3];15}16 17// CHECK: declare noundef nonnull ptr @_Znwm(i64 noundef) [[ATTR_NOBUILTIN:#[^ ]*]]18// CHECK: declare void @_ZdlPvm(ptr noundef, i64 noundef) [[ATTR_NOBUILTIN_NOUNWIND:#[^ ]*]]19// CHECK: declare noundef nonnull ptr @_Znam(i64 noundef) [[ATTR_NOBUILTIN]]20// CHECK: declare void @_ZdaPv(ptr noundef) [[ATTR_NOBUILTIN_NOUNWIND]]21 22namespace std {23  struct nothrow_t {};24}25std::nothrow_t nothrow;26 27// Declare the reserved placement operators.28void *operator new(size_t, void*) throw();29void operator delete(void*, void*) throw();30void *operator new[](size_t, void*) throw();31void operator delete[](void*, void*) throw();32 33// Declare the replaceable global allocation operators.34void *operator new(size_t, const std::nothrow_t &) throw();35void *operator new[](size_t, const std::nothrow_t &) throw();36void operator delete(void *, const std::nothrow_t &) throw();37void operator delete[](void *, const std::nothrow_t &) throw();38 39// Declare some other placemenet operators.40void *operator new(size_t, void*, bool) throw();41void *operator new[](size_t, void*, bool) throw();42 43void t2(int* a) {44  int* b = new (a) int;45}46 47struct S {48  int a;49};50 51// POD types.52void t3() {53  int *a = new int(10);54  _Complex int* b = new _Complex int(10i);55 56  S s;57  s.a = 10;58  S *sp = new S(s);59}60 61// Non-POD62struct T {63  T();64  int a;65};66 67void t4() {68  // CHECK: call void @_ZN1TC1Ev69  T *t = new T;70}71 72struct T2 {73  int a;74  T2(int, int);75};76 77void t5() {78  // CHECK: call void @_ZN2T2C1Eii79  T2 *t2 = new T2(10, 10);80}81 82int *t6() {83  // Null check.84  return new (0) int(10);85}86 87void t7() {88  new int();89}90 91struct U {92  ~U();93};94 95void t8(int n) {96  new int[10];97  new int[n];98 99  // Non-POD100  new T[10];101  new T[n];102 103  // Cookie required104  new U[10];105  new U[n];106}107 108void t9() {109  bool b;110 111  new bool(true);112  new (&b) bool(true);113}114 115struct A {116  void* operator new(__typeof(sizeof(int)), int, float, ...);117  A();118};119 120A* t10() {121   // CHECK: @_ZN1AnwEmifz122  return new(1, 2, 3.45, 100) A;123}124 125// CHECK-LABEL: define{{.*}} void @_Z3t11i126struct B { int a; };127struct Bmemptr { int Bmemptr::* memptr; int a; };128 129void t11(int n) {130  // CHECK: call noalias noundef nonnull ptr @_Znwm131  // CHECK: call void @llvm.memset.p0.i64(132  B* b = new B();133 134  // CHECK: call noalias noundef nonnull ptr @_Znam135  // CHECK: {{call void.*llvm.memset.p0.i64.*i8 0, i64 %}}136  B *b2 = new B[n]();137 138  // CHECK: call noalias noundef nonnull ptr @_Znam139  // CHECK: call void @llvm.memcpy.p0.p0.i64140  // CHECK: br141  Bmemptr *b_memptr = new Bmemptr[n]();142 143  // CHECK: ret void144}145 146struct Empty { };147 148// We don't need to initialize an empty class.149// CHECK-LABEL: define{{.*}} void @_Z3t12v150void t12() {151  // CHECK: call noalias noundef nonnull ptr @_Znam152  // CHECK-NOT: br153  (void)new Empty[10];154 155  // CHECK: call noalias noundef nonnull ptr @_Znam156  // CHECK-NOT: br157  (void)new Empty[10]();158 159  // CHECK: ret void160}161 162// Zero-initialization163// CHECK-LABEL: define{{.*}} void @_Z3t13i164void t13(int n) {165  // CHECK: call noalias noundef nonnull ptr @_Znwm166  // CHECK: store i32 0, ptr167  (void)new int();168 169  // CHECK: call noalias noundef nonnull ptr @_Znam170  // CHECK: {{call void.*llvm.memset.p0.i64.*i8 0, i64 %}}171  (void)new int[n]();172 173  // CHECK-NEXT: ret void174}175 176struct Alloc{177  int x;178  void* operator new[](size_t size);179  __attribute__((returns_nonnull)) void *operator new[](size_t size, const std::nothrow_t &) throw();180  void operator delete[](void* p);181  ~Alloc();182};183 184void f() {185  // CHECK: call noundef ptr @_ZN5AllocnaEm(i64 noundef 808)186  // CHECK: store i64 200187  // CHECK: call void @_ZN5AllocD1Ev(188  // CHECK: call void @_ZN5AllocdaEPv(ptr189  delete[] new Alloc[10][20];190  // CHECK: [[P:%.*]] = call noundef nonnull ptr @_ZN5AllocnaEmRKSt9nothrow_t(i64 noundef 808, {{.*}}) [[ATTR_NOUNWIND:#[^ ]*]]191  // CHECK-NOT: icmp eq ptr [[P]], null192  // CHECK: store i64 200193  delete[] new (nothrow) Alloc[10][20];194  // CHECK: call noalias noundef nonnull ptr @_Znwm195  // CHECK: call void @_ZdlPvm(ptr noundef {{%.*}}, i64 noundef 1)196  delete new bool;197  // CHECK: ret void198}199 200namespace test15 {201  struct A { A(); ~A(); };202 203  // CHECK-LABEL:    define{{.*}} void @_ZN6test156test0aEPv(204  // CHECK:      [[P:%.*]] = load ptr, ptr205  // CHECK-NOT:  icmp eq ptr [[P]], null206  // CHECK-NOT:  br i1207  // CHECK-NEXT: call void @_ZN6test151AC1Ev(ptr {{[^,]*}} [[P]])208  void test0a(void *p) {209    new (p) A();210  }211 212  // CHECK-LABEL:    define{{.*}} void @_ZN6test156test0bEPv(213  // CHECK:      [[P0:%.*]] = load ptr, ptr214  // CHECK:      [[P:%.*]] = call noundef ptr @_ZnwmPvb(i64 noundef 1, ptr noundef [[P0]]215  // CHECK-NEXT: icmp eq ptr [[P]], null216  // CHECK-NEXT: br i1217  // CHECK: call void @_ZN6test151AC1Ev(ptr {{[^,]*}} [[P]])218  void test0b(void *p) {219    new (p, true) A();220  }221 222  // CHECK-LABEL:    define{{.*}} void @_ZN6test156test1aEPv(223  // CHECK:      [[P:%.*]] = load ptr, ptr224  // CHECK-NOT:  icmp eq ptr [[P]], null225  // CHECK-NOT:  br i1226  // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A:.*]], ptr [[P]], i64 5227  // CHECK-NEXT: br label228  // CHECK:      [[CUR:%.*]] = phi ptr [ [[P]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]229  // CHECK-NEXT: call void @_ZN6test151AC1Ev(ptr {{[^,]*}} [[CUR]])230  // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]], ptr [[CUR]], i64 1231  // CHECK-NEXT: [[DONE:%.*]] = icmp eq ptr [[NEXT]], [[END]]232  // CHECK-NEXT: br i1 [[DONE]]233  void test1a(void *p) {234    new (p) A[5];235  }236 237  // CHECK-LABEL:    define{{.*}} void @_ZN6test156test1bEPv(238  // CHECK:      [[P0:%.*]] = load ptr, ptr239  // CHECK:      [[P:%.*]] = call noundef ptr @_ZnamPvb(i64 noundef 13, ptr noundef [[P0]]240  // CHECK-NEXT: icmp eq ptr [[P]], null241  // CHECK-NEXT: br i1242  // CHECK:      [[AFTER_COOKIE:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 8243  // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], ptr [[AFTER_COOKIE]], i64 5244  // CHECK-NEXT: br label245  // CHECK:      [[CUR:%.*]] = phi ptr [ [[AFTER_COOKIE]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ]246  // CHECK-NEXT: call void @_ZN6test151AC1Ev(ptr {{[^,]*}} [[CUR]])247  // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]], ptr [[CUR]], i64 1248  // CHECK-NEXT: [[DONE:%.*]] = icmp eq ptr [[NEXT]], [[END]]249  // CHECK-NEXT: br i1 [[DONE]]250  void test1b(void *p) {251    new (p, true) A[5];252  }253 254  // TODO: it's okay if all these size calculations get dropped.255  // FIXME: maybe we should try to throw on overflow?256  // CHECK-LABEL:    define{{.*}} void @_ZN6test155test2EPvi(257  // CHECK:      [[N:%.*]] = load i32, ptr258  // CHECK-NEXT: [[T0:%.*]] = sext i32 [[N]] to i64259  // CHECK-NEXT: [[P:%.*]] = load ptr, ptr260  // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq i64 [[T0]], 0261  // CHECK-NEXT: br i1 [[ISEMPTY]],262  // CHECK:      [[END:%.*]] = getelementptr inbounds [[A]], ptr [[P]], i64 [[T0]]263  // CHECK-NEXT: br label264  // CHECK:      [[CUR:%.*]] = phi ptr [ [[P]],265  // CHECK-NEXT: call void @_ZN6test151AC1Ev(ptr {{[^,]*}} [[CUR]])266  void test2(void *p, int n) {267    new (p) A[n];268  }269}270 271namespace PR10197 {272  // CHECK-LABEL: define weak_odr void @_ZN7PR101971fIiEEvv()273  template<typename T>274  void f() {275    // CHECK: [[CALL:%.*]] = call noalias noundef nonnull ptr @_Znwm276    new T;277    // CHECK-NEXT: ret void278  }279 280  template void f<int>();281}282 283namespace PR11523 {284  class MyClass;285  typedef int MyClass::* NewTy;286  // CHECK-LABEL: define{{.*}} ptr @_ZN7PR115231fEv287  // CHECK: store i64 -1288  NewTy* f() { return new NewTy[2](); }289}290 291namespace PR11757 {292  // Make sure we elide the copy construction.293  struct X { X(); X(const X&); };294  X* a(X* x) { return new X(X()); }295  // CHECK: define {{.*}} @_ZN7PR117571aEPNS_1XE296  // CHECK: [[CALL:%.*]] = call noalias noundef nonnull ptr @_Znwm297  // CHECK: ret {{.*}} [[CALL]]298}299 300namespace PR13380 {301  struct A { A() {} };302  struct B : public A { int x; };303  // CHECK-LABEL: define{{.*}} ptr @_ZN7PR133801fEv304  // CHECK: call noalias noundef nonnull ptr @_Znam(305  // CHECK: call void @llvm.memset.p0306  // CHECK-NEXT: call void @_ZN7PR133801BC1Ev307  void* f() { return new B[2](); }308}309 310struct MyPlacementType {} mpt;311void *operator new(size_t, MyPlacementType);312 313namespace N3664 {314  struct S { S() throw(int); };315 316  // CHECK-LABEL: define{{.*}} void @_ZN5N36641fEv317  void f() {318    // CHECK: call noalias noundef nonnull ptr @_Znwm(i64 noundef 4) [[ATTR_BUILTIN_NEW:#[^ ]*]]319    int *p = new int; // expected-note {{allocated with 'new' here}}320    // CHECK: call void @_ZdlPvm({{.*}}) [[ATTR_BUILTIN_DELETE:#[^ ]*]]321    delete p;322 323    // CHECK: call noalias noundef nonnull ptr @_Znam(i64 noundef 12) [[ATTR_BUILTIN_NEW]]324    int *q = new int[3];325    // CHECK: call void @_ZdaPv({{.*}}) [[ATTR_BUILTIN_DELETE]]326    delete[] p; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}}327 328    // CHECK: call noalias noundef ptr @_ZnamRKSt9nothrow_t(i64 noundef 3, {{.*}}) [[ATTR_NOBUILTIN_NOUNWIND_ALLOCSIZE:#[^ ]*]]329    (void) new (nothrow) S[3];330 331    // CHECK: call noundef ptr @_Znwm15MyPlacementType(i64 noundef 4){{$}}332    (void) new (mpt) int;333  }334 335  // CHECK: declare noundef ptr @_ZnamRKSt9nothrow_t(i64 noundef, {{.*}}) [[ATTR_NOBUILTIN_NOUNWIND_ALLOCSIZE:#[^ ]*]]336 337  // CHECK-LABEL: define{{.*}} void @_ZN5N36641gEv338  void g() {339    // It's OK for there to be attributes here, so long as we don't have a340    // 'builtin' attribute.341    // CHECK: call noalias noundef nonnull ptr @_Znwm(i64 noundef 4) {{#[^ ]*}}{{$}}342    int *p = (int*)operator new(4);343    // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_NOUNWIND:#[^ ]*]]344    operator delete(p);345 346    // CHECK: call noalias noundef nonnull ptr @_Znam(i64 noundef 12) {{#[^ ]*}}{{$}}347    int *q = (int*)operator new[](12);348    // CHECK: call void @_ZdaPv({{.*}}) [[ATTR_NOUNWIND]]349    operator delete [](p);350 351    // CHECK: call noalias noundef ptr @_ZnamRKSt9nothrow_t(i64 noundef 3, {{.*}}) [[ATTR_NOUNWIND_ALLOCSIZE:#[^ ]*]]352    (void) operator new[](3, nothrow);353  }354}355 356namespace builtins {357  // CHECK-LABEL: define{{.*}} void @_ZN8builtins1fEv358  void f() {359    // CHECK: call noalias noundef nonnull ptr @_Znwm(i64 noundef 4) [[ATTR_BUILTIN_NEW]]360    // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE]]361    __builtin_operator_delete(__builtin_operator_new(4));362  }363}364 365// CHECK-DAG: attributes [[ATTR_NOBUILTIN]] = {{[{].*}} nobuiltin allocsize(0) {{.*[}]}}366// CHECK-DAG: attributes [[ATTR_NOBUILTIN_NOUNWIND]] = {{[{].*}} nobuiltin nounwind {{.*[}]}}367// CHECK-DAG: attributes [[ATTR_NOBUILTIN_NOUNWIND_ALLOCSIZE]] = {{[{].*}} nobuiltin nounwind allocsize(0) {{.*[}]}}368 369// CHECK-DAG: attributes [[ATTR_BUILTIN_NEW]] = {{[{].*}} builtin {{.*[}]}}370// CHECK-DAG: attributes [[ATTR_BUILTIN_DELETE]] = {{[{].*}} builtin {{.*[}]}}371 372// The ([^b}|...) monstrosity is matching a character that's not the start of 'builtin'.373// Add more letters if this matches some other attribute.374// CHECK-DAG: attributes [[ATTR_NOUNWIND]] = {{([^b]|b[^u]|bu[^i]|bui[^l])*}} nounwind {{([^b]|b[^u]|bu[^i]|bui[^l])*$}}375// CHECK-DAG: attributes [[ATTR_NOUNWIND_ALLOCSIZE]] = {{([^b]|b[^u]|bu[^i]|bui[^l])*}} nounwind allocsize(0) {{([^b]|b[^u]|bu[^i]|bui[^l])*$}}376