diff options
Diffstat (limited to 'test/Analysis/new-ctor-recursive.cpp')
-rw-r--r-- | test/Analysis/new-ctor-recursive.cpp | 118 |
1 files changed, 0 insertions, 118 deletions
diff --git a/test/Analysis/new-ctor-recursive.cpp b/test/Analysis/new-ctor-recursive.cpp deleted file mode 100644 index f21795d1739a..000000000000 --- a/test/Analysis/new-ctor-recursive.cpp +++ /dev/null @@ -1,118 +0,0 @@ -// 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 - -void clang_analyzer_eval(bool); -void clang_analyzer_dump(int); - -typedef __typeof__(sizeof(int)) size_t; - -void *conjure(); -void exit(int); - -struct S; - -S *global_s; - -// Recursive operator kinda placement new. -void *operator new(size_t size, S *place); - -enum class ConstructionKind : char { - Garbage, - Recursive -}; - -struct S { -public: - int x; - S(): x(1) {} - S(int y): x(y) {} - - S(ConstructionKind k) { - switch (k) { - case ConstructionKind::Recursive: { // Call one more operator new 'r'ecursively. - S *s = new (nullptr) S(5); - x = s->x + 1; - global_s = s; - return; - } - case ConstructionKind::Garbage: { - // Leaves garbage in 'x'. - } - } - } - ~S() {} -}; - -// Do not try this at home! -void *operator new(size_t size, S *place) { - if (!place) - return new S(); - return place; -} - -void testThatCharConstructorIndeedYieldsGarbage() { - S *s = new S(ConstructionKind::Garbage); - clang_analyzer_eval(s->x == 0); // expected-warning{{UNKNOWN}} - clang_analyzer_eval(s->x == 1); // expected-warning{{UNKNOWN}} - // FIXME: This should warn, but MallocChecker doesn't default-bind regions - // returned by standard operator new to garbage. - s->x += 1; // no-warning - delete s; -} - - -void testChainedOperatorNew() { - S *s; - // * Evaluate standard new. - // * Evaluate constructor S(3). - // * Bind value for standard new. - // * Evaluate our custom new. - // * Evaluate constructor S(Garbage). - // * Bind value for our custom new. - s = new (new S(3)) S(ConstructionKind::Garbage); - clang_analyzer_eval(s->x == 3); // expected-warning{{TRUE}} - // expected-warning@+9{{Potential leak of memory pointed to by 's'}} - - // * Evaluate standard new. - // * Evaluate constructor S(Garbage). - // * Bind value for standard new. - // * Evaluate our custom new. - // * Evaluate constructor S(4). - // * Bind value for our custom new. - s = new (new S(ConstructionKind::Garbage)) S(4); - clang_analyzer_eval(s->x == 4); // expected-warning{{TRUE}} - delete s; - - // -> Enter our custom new (nullptr). - // * Evaluate standard new. - // * Inline constructor S(). - // * Bind value for standard new. - // <- Exit our custom new (nullptr). - // * Evaluate constructor S(Garbage). - // * Bind value for our custom new. - s = new (nullptr) S(ConstructionKind::Garbage); - clang_analyzer_eval(s->x == 1); // expected-warning{{TRUE}} - delete s; - - // -> Enter our custom new (nullptr). - // * Evaluate standard new. - // * Inline constructor S(). - // * Bind value for standard new. - // <- Exit our custom new (nullptr). - // -> Enter constructor S(Recursive). - // -> Enter our custom new (nullptr). - // * Evaluate standard new. - // * Inline constructor S(). - // * Bind value for standard new. - // <- Exit our custom new (nullptr). - // * Evaluate constructor S(5). - // * Bind value for our custom new (nullptr). - // * Assign that value to global_s. - // <- Exit constructor S(Recursive). - // * Bind value for our custom new (nullptr). - global_s = nullptr; - s = new (nullptr) S(ConstructionKind::Recursive); - clang_analyzer_eval(global_s); // expected-warning{{TRUE}} - clang_analyzer_eval(global_s->x == 5); // expected-warning{{TRUE}} - clang_analyzer_eval(s->x == 6); // expected-warning{{TRUE}} - delete s; -} |