[RISCV] Add shrinkwrap test cases showing gaps in current impl
[llvm-project.git] / clang / test / Analysis / ArrayDelete.cpp
blob6887e0a35fb8bd882e3b1c6d38e48056aff44365
1 // RUN: %clang_cc1 -analyze -analyzer-checker=cplusplus.ArrayDelete -std=c++11 -verify -analyzer-output=text %s
3 struct Base {
4 virtual ~Base() = default;
5 };
7 struct Derived : public Base {};
9 struct DoubleDerived : public Derived {};
11 Derived *get();
13 Base *create() {
14 Base *b = new Derived[3]; // expected-note{{Casting from 'Derived' to 'Base' here}}
15 return b;
18 void sink(Base *b) {
19 delete[] b; // expected-warning{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
20 // expected-note@-1{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
23 void sink_cast(Base *b) {
24 delete[] static_cast<Derived*>(b); // no-warning
27 void sink_derived(Derived *d) {
28 delete[] d; // no-warning
31 void same_function() {
32 Base *sd = new Derived[10]; // expected-note{{Casting from 'Derived' to 'Base' here}}
33 delete[] sd; // expected-warning{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
34 // expected-note@-1{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
36 Base *dd = new DoubleDerived[10]; // expected-note{{Casting from 'DoubleDerived' to 'Base' here}}
37 delete[] dd; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
38 // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
41 void different_function() {
42 Base *assigned = get(); // expected-note{{Casting from 'Derived' to 'Base' here}}
43 delete[] assigned; // expected-warning{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
44 // expected-note@-1{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
46 Base *indirect;
47 indirect = get(); // expected-note{{Casting from 'Derived' to 'Base' here}}
48 delete[] indirect; // expected-warning{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
49 // expected-note@-1{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
51 Base *created = create(); // expected-note{{Calling 'create'}}
52 // expected-note@-1{{Returning from 'create'}}
53 delete[] created; // expected-warning{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
54 // expected-note@-1{{Deleting an array of 'Derived' objects as their base class 'Base' is undefined}}
56 Base *sb = new Derived[10]; // expected-note{{Casting from 'Derived' to 'Base' here}}
57 sink(sb); // expected-note{{Calling 'sink'}}
60 void safe_function() {
61 Derived *d = new Derived[10];
62 delete[] d; // no-warning
64 Base *b = new Derived[10];
65 delete[] static_cast<Derived*>(b); // no-warning
67 Base *sb = new Derived[10];
68 sink_cast(sb); // no-warning
70 Derived *sd = new Derived[10];
71 sink_derived(sd); // no-warning
74 void multiple_derived() {
75 Base *b = new DoubleDerived[10]; // expected-note{{Casting from 'DoubleDerived' to 'Base' here}}
76 delete[] b; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
77 // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
79 Base *b2 = new DoubleDerived[10]; // expected-note{{Casting from 'DoubleDerived' to 'Base' here}}
80 Derived *d2 = static_cast<Derived*>(b2); // expected-note{{Casting from 'Base' to 'Derived' here}}
81 delete[] d2; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}
82 // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}
84 Derived *d3 = new DoubleDerived[10]; // expected-note{{Casting from 'DoubleDerived' to 'Derived' here}}
85 Base *b3 = d3; // expected-note{{Casting from 'Derived' to 'Base' here}}
86 delete[] b3; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
87 // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Base' is undefined}}
89 Base *b4 = new DoubleDerived[10];
90 Derived *d4 = static_cast<Derived*>(b4);
91 DoubleDerived *dd4 = static_cast<DoubleDerived*>(d4);
92 delete[] dd4; // no-warning
94 Base *b5 = new DoubleDerived[10]; // expected-note{{Casting from 'DoubleDerived' to 'Base' here}}
95 DoubleDerived *dd5 = static_cast<DoubleDerived*>(b5); // expected-note{{Casting from 'Base' to 'DoubleDerived' here}}
96 Derived *d5 = dd5; // expected-note{{Casting from 'DoubleDerived' to 'Derived' here}}
97 delete[] d5; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}
98 // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}
101 void unrelated_casts() {
102 Base *b = new DoubleDerived[10]; // expected-note{{Casting from 'DoubleDerived' to 'Base' here}}
103 Base &b2 = *b; // no-note: See the FIXME.
105 // FIXME: Displaying casts of reference types is not supported.
106 Derived &d2 = static_cast<Derived&>(b2); // no-note: See the FIXME.
108 Derived *d = &d2; // no-note: See the FIXME.
109 delete[] d; // expected-warning{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}
110 // expected-note@-1{{Deleting an array of 'DoubleDerived' objects as their base class 'Derived' is undefined}}