diff options
Diffstat (limited to 'test/Analysis/dtor.cpp')
-rw-r--r-- | test/Analysis/dtor.cpp | 71 |
1 files changed, 70 insertions, 1 deletions
diff --git a/test/Analysis/dtor.cpp b/test/Analysis/dtor.cpp index 11ce0d57ef4f..8d6e30a6c27c 100644 --- a/test/Analysis/dtor.cpp +++ b/test/Analysis/dtor.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors -Wno-null-dereference -verify %s +// RUN: %clang_cc1 -analyze -analyzer-checker=core,unix.Malloc,debug.ExprInspection -analyzer-config c++-inlining=destructors,cfg-temporary-dtors=true -Wno-null-dereference -verify %s void clang_analyzer_eval(bool); void clang_analyzer_checkInlined(bool); @@ -374,6 +374,70 @@ namespace LifetimeExtension { clang_analyzer_eval(SaveOnDestruct::lastOutput == 42); // expected-warning{{TRUE}} } + struct NRCheck { + bool bool_; + NRCheck():bool_(true) {} + ~NRCheck() __attribute__((noreturn)); + operator bool() const { return bool_; } + }; + + struct CheckAutoDestructor { + bool bool_; + CheckAutoDestructor():bool_(true) {} + operator bool() const { return bool_; } + }; + + struct CheckCustomDestructor { + bool bool_; + CheckCustomDestructor():bool_(true) {} + ~CheckCustomDestructor(); + operator bool() const { return bool_; } + }; + + bool testUnnamedNR() { + if (NRCheck()) + return true; + return false; + } + + bool testNamedNR() { + if (NRCheck c = NRCheck()) + return true; + return false; + } + + bool testUnnamedAutoDestructor() { + if (CheckAutoDestructor()) + return true; + return false; + } + + bool testNamedAutoDestructor() { + if (CheckAutoDestructor c = CheckAutoDestructor()) + return true; + return false; + } + + bool testUnnamedCustomDestructor() { + if (CheckCustomDestructor()) + return true; + return false; + } + + // This case used to cause an unexpected "Undefined or garbage value returned + // to caller" warning + bool testNamedCustomDestructor() { + if (CheckCustomDestructor c = CheckCustomDestructor()) + return true; + return false; + } + + bool testMultipleTemporariesCustomDestructor() { + if (CheckCustomDestructor c = (CheckCustomDestructor(), CheckCustomDestructor())) + return true; + return false; + } + class VirtualDtorBase { public: int value; @@ -416,6 +480,11 @@ namespace NoReturn { f(&x); *x = 47; // no warning } + + void g2(int *x) { + if (! x) NR(); + *x = 47; // no warning + } } namespace PseudoDtor { |