aboutsummaryrefslogtreecommitdiff
path: root/test/Analysis/dtor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/Analysis/dtor.cpp')
-rw-r--r--test/Analysis/dtor.cpp71
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 {