Home | History | Annotate | Download | only in SemaCXX
      1 // Test without PCH
      2 // RUN: %clang_cc1 -fsyntax-only -include %S/delete-mismatch.h -fdiagnostics-parseable-fixits -std=c++11 %s 2>&1 | FileCheck %s
      3 
      4 // Test with PCH
      5 // RUN: %clang_cc1 -x c++-header -std=c++11 -emit-pch -o %t %S/delete-mismatch.h
      6 // RUN: %clang_cc1 -std=c++11 -include-pch %t -DWITH_PCH -fsyntax-only -verify %s -ast-dump
      7 
      8 void f(int a[10][20]) {
      9   delete a; // expected-warning {{'delete' applied to a pointer-to-array type}}
     10   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:9}:"[]"
     11 }
     12 namespace MemberCheck {
     13 struct S {
     14   int *a = new int[5]; // expected-note4 {{allocated with 'new[]' here}}
     15   int *b;
     16   int *c;
     17   static int *d;
     18   S();
     19   S(int);
     20   ~S() {
     21     delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
     22     delete b;   // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
     23     delete[] c; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}}
     24   }
     25   void f();
     26 };
     27 
     28 void S::f()
     29 {
     30   delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
     31   delete b; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
     32 }
     33 
     34 S::S()
     35 : b(new int[1]), c(new int) {} // expected-note3 {{allocated with 'new[]' here}}
     36 // expected-note@-1 {{allocated with 'new' here}}
     37 
     38 S::S(int i)
     39 : b(new int[i]), c(new int) {} // expected-note3 {{allocated with 'new[]' here}}
     40 // expected-note@-1 {{allocated with 'new' here}}
     41 
     42 struct S2 : S {
     43   ~S2() {
     44     delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
     45   }
     46 };
     47 int *S::d = new int[42]; // expected-note {{allocated with 'new[]' here}}
     48 void f(S *s) {
     49   int *a = new int[1]; // expected-note {{allocated with 'new[]' here}}
     50   delete a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
     51   delete s->a; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
     52   delete s->b; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
     53   delete s->c;
     54   delete s->d;
     55   delete S::d; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
     56 }
     57 
     58 // At least one constructor initializes field with matching form of 'new'.
     59 struct MatchingNewIsOK {
     60   int *p;
     61   bool is_array_;
     62   MatchingNewIsOK() : p{new int}, is_array_(false) {}
     63   explicit MatchingNewIsOK(unsigned c) : p{new int[c]}, is_array_(true) {}
     64   ~MatchingNewIsOK() {
     65     if (is_array_)
     66       delete[] p;
     67     else
     68       delete p;
     69   }
     70 };
     71 
     72 // At least one constructor's body is missing; no proof of mismatch.
     73 struct CantProve_MissingCtorDefinition {
     74   int *p;
     75   CantProve_MissingCtorDefinition();
     76   CantProve_MissingCtorDefinition(int);
     77   ~CantProve_MissingCtorDefinition();
     78 };
     79 
     80 CantProve_MissingCtorDefinition::CantProve_MissingCtorDefinition()
     81   : p(new int)
     82 { }
     83 
     84 CantProve_MissingCtorDefinition::~CantProve_MissingCtorDefinition()
     85 {
     86   delete[] p;
     87 }
     88 
     89 struct base {};
     90 struct derived : base {};
     91 struct InitList {
     92   base *p, *p2 = nullptr, *p3{nullptr}, *p4;
     93   InitList(unsigned c) : p(new derived[c]), p4(nullptr) {}  // expected-note {{allocated with 'new[]' here}}
     94   InitList(unsigned c, unsigned) : p{new derived[c]}, p4{nullptr} {} // expected-note {{allocated with 'new[]' here}}
     95   ~InitList() {
     96     delete p; // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
     97     delete [] p;
     98     delete p2;
     99     delete [] p3;
    100     delete p4;
    101   }
    102 };
    103 }
    104 
    105 namespace NonMemberCheck {
    106 #define DELETE_ARRAY(x) delete[] (x)
    107 #define DELETE(x) delete (x)
    108 void f() {
    109   int *a = new int(5); // expected-note2 {{allocated with 'new' here}}
    110   delete[] a;          // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}}
    111   int *b = new int;
    112   delete b;
    113   int *c{new int};    // expected-note {{allocated with 'new' here}}
    114   int *d{new int[1]}; // expected-note2 {{allocated with 'new[]' here}}
    115   delete  [    ] c;   // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}}
    116   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:17}:""
    117   delete d;           // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
    118   // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:9-[[@LINE-1]]:9}:"[]"
    119   DELETE_ARRAY(a);    // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}}
    120   DELETE(d);          // expected-warning {{'delete' applied to a pointer that was allocated with 'new[]'; did you mean 'delete[]'?}}
    121 }
    122 }
    123 
    124 namespace MissingInitializer {
    125 template<typename T>
    126 struct Base {
    127   struct S {
    128     const T *p1 = nullptr;
    129     const T *p2 = new T[3];
    130   };
    131 };
    132 
    133 void null_init(Base<double>::S s) {
    134   delete s.p1;
    135   delete s.p2;
    136 }
    137 }
    138 
    139 #ifndef WITH_PCH
    140 pch_test::X::X()
    141   : a(new int[1])  // expected-note{{allocated with 'new[]' here}}
    142 { }
    143 pch_test::X::X(int i)
    144   : a(new int[i])  // expected-note{{allocated with 'new[]' here}}
    145 { }
    146 #endif
    147