90 lines · cpp
1// RUN: %clangxx_asan -fsized-deallocation -O0 %s -o %t2// RUN: not %run %t scalar 2>&1 | FileCheck %s -check-prefix=SCALAR3// RUN: %env_asan_opts=new_delete_type_mismatch=1 not %run %t scalar 2>&1 | FileCheck %s -check-prefix=SCALAR4// RUN: not %run %t array 2>&1 | FileCheck %s -check-prefix=ARRAY5// RUN: %env_asan_opts=new_delete_type_mismatch=1 not %run %t array 2>&1 | FileCheck %s -check-prefix=ARRAY6// RUN: %env_asan_opts=new_delete_type_mismatch=0 %run %t scalar7// RUN: %env_asan_opts=new_delete_type_mismatch=0 %run %t array8 9#include <new>10#include <stdio.h>11#include <string>12 13inline void break_optimization(void *arg) {14 __asm__ __volatile__("" : : "r" (arg) : "memory");15}16 17struct S12 {18 int a, b, c;19};20 21struct S20 {22 int a, b, c, d, e;23};24 25struct D1 {26 int a, b, c;27 ~D1() { fprintf(stderr, "D1::~D1\n"); }28};29 30struct D2 {31 int a, b, c, d, e;32 ~D2() { fprintf(stderr, "D2::~D2\n"); }33};34 35void Del12(S12 *x) {36 break_optimization(x);37 delete x;38}39void Del12NoThrow(S12 *x) {40 break_optimization(x);41 operator delete(x, std::nothrow);42}43void Del12Ar(S12 *x) {44 break_optimization(x);45 delete [] x;46}47void Del12ArNoThrow(S12 *x) {48 break_optimization(x);49 operator delete[](x, std::nothrow);50}51 52int 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 FAR68 // ARRAY: OK SO FAR69 if (flag == "scalar") {70 // Here asan should bark as we are passing a wrong type of pointer71 // to sized delete.72 Del12(reinterpret_cast<S12*>(new S20));73 // SCALAR: AddressSanitizer: new-delete-type-mismatch74 // 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 region78 // SCALAR: SUMMARY: AddressSanitizer: new-delete-type-mismatch79 } else if (flag == "array") {80 D1 *d1 = reinterpret_cast<D1*>(new D2[10]);81 break_optimization(d1);82 delete [] d1;83 // ARRAY-NOT: D2::~D284 // ARRAY: D1::~D185 // ARRAY: AddressSanitizer: new-delete-type-mismatch86 // ARRAY: size of the allocated type: 20{{4|8}} bytes;87 // ARRAY: size of the deallocated type: 12{{4|8}} bytes.88 }89}90