[ELF] Avoid make in elf::writeARMCmseImportLib
[llvm-project.git] / clang / test / Analysis / new-ctor-recursive.cpp
blob4aca1d832bf2805af9a3a817ed2aba14299b97a2
1 // RUN: %clang_analyze_cc1 -std=c++11 -analyzer-checker=core,cplusplus.NewDelete,cplusplus.NewDeleteLeaks,debug.ExprInspection -analyzer-config c++-allocator-inlining=true -std=c++11 -verify -analyzer-config eagerly-assume=false %s
3 void clang_analyzer_eval(bool);
4 void clang_analyzer_dump(int);
6 typedef __typeof__(sizeof(int)) size_t;
8 void *conjure();
9 void exit(int);
11 struct S;
13 S *global_s;
15 // Recursive operator kinda placement new.
16 void *operator new(size_t size, S *place);
18 enum class ConstructionKind : char {
19 Garbage,
20 Recursive
23 struct S {
24 public:
25 int x;
26 S(): x(1) {}
27 S(int y): x(y) {}
29 S(ConstructionKind k) {
30 switch (k) {
31 case ConstructionKind::Recursive: { // Call one more operator new 'r'ecursively.
32 S *s = new (nullptr) S(5);
33 x = s->x + 1;
34 global_s = s;
35 return;
37 case ConstructionKind::Garbage: {
38 // Leaves garbage in 'x'.
42 ~S() {}
45 // Do not try this at home!
46 void *operator new(size_t size, S *place) {
47 if (!place)
48 return new S();
49 return place;
52 void testThatCharConstructorIndeedYieldsGarbage() {
53 S *s = new S(ConstructionKind::Garbage);
54 clang_analyzer_eval(s->x == 0); // expected-warning{{The left operand of '==' is a garbage value [core.UndefinedBinaryOperatorResult]}}
55 clang_analyzer_eval(s->x == 1);
56 s->x += 1;
57 delete s;
61 void testChainedOperatorNew() {
62 S *s;
63 // * Evaluate standard new.
64 // * Evaluate constructor S(3).
65 // * Bind value for standard new.
66 // * Evaluate our custom new.
67 // * Evaluate constructor S(Garbage).
68 // * Bind value for our custom new.
69 s = new (new S(3)) S(ConstructionKind::Garbage);
70 clang_analyzer_eval(s->x == 3); // expected-warning{{TRUE}}
71 // expected-warning@+9{{Potential leak of memory pointed to by 's'}}
73 // * Evaluate standard new.
74 // * Evaluate constructor S(Garbage).
75 // * Bind value for standard new.
76 // * Evaluate our custom new.
77 // * Evaluate constructor S(4).
78 // * Bind value for our custom new.
79 s = new (new S(ConstructionKind::Garbage)) S(4);
80 clang_analyzer_eval(s->x == 4); // expected-warning{{TRUE}}
81 delete s;
83 // -> Enter our custom new (nullptr).
84 // * Evaluate standard new.
85 // * Inline constructor S().
86 // * Bind value for standard new.
87 // <- Exit our custom new (nullptr).
88 // * Evaluate constructor S(Garbage).
89 // * Bind value for our custom new.
90 s = new (nullptr) S(ConstructionKind::Garbage);
91 clang_analyzer_eval(s->x == 1); // expected-warning{{TRUE}}
92 delete s;
94 // -> Enter our custom new (nullptr).
95 // * Evaluate standard new.
96 // * Inline constructor S().
97 // * Bind value for standard new.
98 // <- Exit our custom new (nullptr).
99 // -> Enter constructor S(Recursive).
100 // -> Enter our custom new (nullptr).
101 // * Evaluate standard new.
102 // * Inline constructor S().
103 // * Bind value for standard new.
104 // <- Exit our custom new (nullptr).
105 // * Evaluate constructor S(5).
106 // * Bind value for our custom new (nullptr).
107 // * Assign that value to global_s.
108 // <- Exit constructor S(Recursive).
109 // * Bind value for our custom new (nullptr).
110 global_s = nullptr;
111 s = new (nullptr) S(ConstructionKind::Recursive);
112 clang_analyzer_eval(global_s); // expected-warning{{TRUE}}
113 clang_analyzer_eval(global_s->x == 5); // expected-warning{{TRUE}}
114 clang_analyzer_eval(s->x == 6); // expected-warning{{TRUE}}
115 delete s;