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