Home | History | Annotate | Download | only in Linux
      1 // RUN: %clangxx_asan -fsized-deallocation -O0 %s -o %t
      2 // RUN:                                                                  not %run %t scalar 2>&1 | FileCheck %s -check-prefix=SCALAR
      3 // RUN: %env_asan_opts=new_delete_type_mismatch=1 not %run %t scalar 2>&1 | FileCheck %s -check-prefix=SCALAR
      4 // RUN:                                                                  not %run %t array  2>&1 | FileCheck %s -check-prefix=ARRAY
      5 // RUN: %env_asan_opts=new_delete_type_mismatch=1 not %run %t array  2>&1 | FileCheck %s -check-prefix=ARRAY
      6 // RUN: %env_asan_opts=new_delete_type_mismatch=0     %run %t scalar
      7 // RUN: %env_asan_opts=new_delete_type_mismatch=0     %run %t array
      8 
      9 #include <new>
     10 #include <stdio.h>
     11 #include <string>
     12 
     13 inline void break_optimization(void *arg) {
     14   __asm__ __volatile__("" : : "r" (arg) : "memory");
     15 }
     16 
     17 struct S12 {
     18   int a, b, c;
     19 };
     20 
     21 struct S20 {
     22   int a, b, c, d, e;
     23 };
     24 
     25 struct D1 {
     26   int a, b, c;
     27   ~D1() { fprintf(stderr, "D1::~D1\n"); }
     28 };
     29 
     30 struct D2 {
     31   int a, b, c, d, e;
     32   ~D2() { fprintf(stderr, "D2::~D2\n"); }
     33 };
     34 
     35 void Del12(S12 *x) {
     36   break_optimization(x);
     37   delete x;
     38 }
     39 void Del12NoThrow(S12 *x) {
     40   break_optimization(x);
     41   operator delete(x, std::nothrow);
     42 }
     43 void Del12Ar(S12 *x) {
     44   break_optimization(x);
     45   delete [] x;
     46 }
     47 void Del12ArNoThrow(S12 *x) {
     48   break_optimization(x);
     49   operator delete[](x, std::nothrow);
     50 }
     51 
     52 int main(int argc, char **argv) {
     53   if (argc != 2) return 1;
     54   std::string flag = argv[1];
     55   // These are correct.
     56   Del12(new S12);
     57   Del12NoThrow(new S12);
     58   Del12Ar(new S12[100]);
     59   Del12ArNoThrow(new S12[100]);
     60 
     61   // Here we pass wrong type of pointer to delete,
     62   // but [] and nothrow variants of delete are not sized.
     63   Del12Ar(reinterpret_cast<S12*>(new S20[100]));
     64   Del12NoThrow(reinterpret_cast<S12*>(new S20));
     65   Del12ArNoThrow(reinterpret_cast<S12*>(new S20[100]));
     66   fprintf(stderr, "OK SO FAR\n");
     67   // SCALAR: OK SO FAR
     68   // ARRAY: OK SO FAR
     69   if (flag == "scalar") {
     70     // Here asan should bark as we are passing a wrong type of pointer
     71     // to sized delete.
     72     Del12(reinterpret_cast<S12*>(new S20));
     73     // SCALAR: AddressSanitizer: new-delete-type-mismatch
     74     // SCALAR:  object passed to delete has wrong type:
     75     // SCALAR:  size of the allocated type:   20 bytes;
     76     // SCALAR:  size of the deallocated type: 12 bytes.
     77     // SCALAR: is located 0 bytes inside of 20-byte region
     78     // SCALAR: SUMMARY: AddressSanitizer: new-delete-type-mismatch
     79   } else if (flag == "array") {
     80     D1 *d1 = reinterpret_cast<D1*>(new D2[10]);
     81     break_optimization(d1);
     82     delete [] d1;
     83     // ARRAY-NOT: D2::~D2
     84     // ARRAY: D1::~D1
     85     // ARRAY: AddressSanitizer: new-delete-type-mismatch
     86     // ARRAY:  size of the allocated type:   20{{4|8}} bytes;
     87     // ARRAY:  size of the deallocated type: 12{{4|8}} bytes.
     88   }
     89 }
     90