summaryrefslogtreecommitdiffstats
path: root/clang/test/Analysis/use-after-move.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/Analysis/use-after-move.cpp')
-rw-r--r--clang/test/Analysis/use-after-move.cpp34
1 files changed, 29 insertions, 5 deletions
diff --git a/clang/test/Analysis/use-after-move.cpp b/clang/test/Analysis/use-after-move.cpp
index 3bb52f164b4..d60f07f095f 100644
--- a/clang/test/Analysis/use-after-move.cpp
+++ b/clang/test/Analysis/use-after-move.cpp
@@ -1,20 +1,26 @@
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\
// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\
-// RUN: -analyzer-config exploration_strategy=unexplored_first_queue
+// RUN: -analyzer-config exploration_strategy=unexplored_first_queue\
+// RUN: -analyzer-checker debug.ExprInspection
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\
// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\
-// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1
+// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\
+// RUN: -analyzer-checker debug.ExprInspection
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\
// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\
// RUN: -analyzer-config exploration_strategy=unexplored_first_queue\
-// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE
+// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE\
+// RUN: -analyzer-checker debug.ExprInspection
// RUN: %clang_analyze_cc1 -analyzer-checker=alpha.cplusplus.Move -verify %s\
// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\
// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\
-// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE
+// RUN: -analyzer-config alpha.cplusplus.Move:Aggressive=true -DAGGRESSIVE\
+// RUN: -analyzer-checker debug.ExprInspection
#include "Inputs/system-header-simulator-cxx.h"
+void clang_analyzer_warnIfReached();
+
class B {
public:
B() = default;
@@ -849,7 +855,19 @@ class HasSTLField {
// expected-note@-4{{Object 'P' is moved}}
// expected-note@-4{{Method called on moved-from object 'P'}}
#endif
- *P += 1; // FIXME: Should warn that the pointer is null.
+
+ // Because that well-defined state is null, dereference is still UB.
+ // Note that in aggressive mode we already warned about 'P',
+ // so no extra warning is generated.
+ *P += 1;
+#ifndef AGGRESSIVE
+ // expected-warning@-2{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}}
+ // expected-note@-14{{Smart pointer 'P' of type 'std::unique_ptr' is reset to null when moved from}}
+ // expected-note@-4{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}}
+#endif
+
+ // The program should have crashed by now.
+ clang_analyzer_warnIfReached(); // no-warning
}
};
@@ -866,3 +884,9 @@ void localUniquePtr(std::unique_ptr<int> P) {
P.get(); // expected-warning{{Method called on moved-from object 'P'}}
// expected-note@-1{{Method called on moved-from object 'P'}}
}
+
+void localUniquePtrWithArrow(std::unique_ptr<A> P) {
+ std::unique_ptr<A> Q = std::move(P); // expected-note{{Smart pointer 'P' of type 'std::unique_ptr' is reset to null when moved from}}
+ P->foo(); // expected-warning{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}}
+ // expected-note@-1{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}}
+}
OpenPOWER on IntegriCloud