forked from OSchip/llvm-project
[analyzer] NFC: MoveChecker: Refactor tests to use -verify=prefix.
This -verify=prefix feature is quite underrated. Differential Revision: https://reviews.llvm.org/D60732 llvm-svn: 358719
This commit is contained in:
parent
5d281ac9ce
commit
6b71e27c94
|
@ -1,31 +1,37 @@
|
|||
// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\
|
||||
// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move %s\
|
||||
// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\
|
||||
// RUN: -analyzer-config exploration_strategy=unexplored_first_queue\
|
||||
// RUN: -analyzer-checker debug.ExprInspection
|
||||
// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\
|
||||
// RUN: -analyzer-checker debug.ExprInspection\
|
||||
// RUN: -verify=expected,peaceful,non-aggressive
|
||||
// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move %s\
|
||||
// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\
|
||||
// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\
|
||||
// RUN: -analyzer-checker debug.ExprInspection
|
||||
// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\
|
||||
// RUN: -analyzer-config exploration_strategy=dfs -DDFS\
|
||||
// RUN: -analyzer-checker debug.ExprInspection\
|
||||
// RUN: -verify=expected,peaceful,non-aggressive
|
||||
// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move %s\
|
||||
// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\
|
||||
// RUN: -analyzer-config exploration_strategy=unexplored_first_queue\
|
||||
// RUN: -analyzer-config cplusplus.Move:WarnOn=KnownsOnly -DPEACEFUL\
|
||||
// RUN: -analyzer-checker debug.ExprInspection
|
||||
// RUN: -analyzer-config cplusplus.Move:WarnOn=KnownsOnly\
|
||||
// RUN: -analyzer-checker debug.ExprInspection\
|
||||
// RUN: -verify=expected,non-aggressive
|
||||
// RUN: %clang_analyze_cc1 -analyzer-checker=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 cplusplus.Move:WarnOn=KnownsOnly -DPEACEFUL\
|
||||
// RUN: -analyzer-checker debug.ExprInspection
|
||||
// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\
|
||||
// RUN: -analyzer-config exploration_strategy=dfs -DDFS\
|
||||
// RUN: -analyzer-config cplusplus.Move:WarnOn=KnownsOnly\
|
||||
// RUN: -analyzer-checker debug.ExprInspection\
|
||||
// RUN: -verify=expected,non-aggressive
|
||||
// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move %s\
|
||||
// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\
|
||||
// RUN: -analyzer-config exploration_strategy=unexplored_first_queue\
|
||||
// RUN: -analyzer-config cplusplus.Move:WarnOn=All -DAGGRESSIVE\
|
||||
// RUN: -analyzer-checker debug.ExprInspection
|
||||
// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move -verify %s\
|
||||
// RUN: -analyzer-config cplusplus.Move:WarnOn=All\
|
||||
// RUN: -analyzer-checker debug.ExprInspection\
|
||||
// RUN: -verify=expected,peaceful,aggressive
|
||||
// RUN: %clang_analyze_cc1 -analyzer-checker=cplusplus.Move %s\
|
||||
// RUN: -std=c++11 -analyzer-output=text -analyzer-config eagerly-assume=false\
|
||||
// RUN: -analyzer-config exploration_strategy=dfs -DDFS=1\
|
||||
// RUN: -analyzer-config cplusplus.Move:WarnOn=All -DAGGRESSIVE\
|
||||
// RUN: -analyzer-checker debug.ExprInspection
|
||||
// RUN: -analyzer-config exploration_strategy=dfs -DDFS\
|
||||
// RUN: -analyzer-config cplusplus.Move:WarnOn=All\
|
||||
// RUN: -analyzer-checker debug.ExprInspection\
|
||||
// RUN: -verify=expected,peaceful,aggressive
|
||||
|
||||
// RUN: not %clang_analyze_cc1 -verify %s \
|
||||
// RUN: -analyzer-checker=core \
|
||||
|
@ -75,10 +81,7 @@ public:
|
|||
moveconstruct(std::move(*a));
|
||||
}
|
||||
A(const A &other) : i(other.i), d(other.d), b(other.b) {}
|
||||
A(A &&other) : i(other.i), d(other.d), b(std::move(other.b)) {
|
||||
#ifdef AGGRESSIVE
|
||||
// expected-note@-2{{Object 'b' is moved}}
|
||||
#endif
|
||||
A(A &&other) : i(other.i), d(other.d), b(std::move(other.b)) { // aggressive-note{{Object 'b' is moved}}
|
||||
}
|
||||
A(A &&other, char *k) {
|
||||
moveconstruct(std::move(other));
|
||||
|
@ -141,33 +144,21 @@ void copyOrMoveCall(A a) {
|
|||
void simpleMoveCtorTest() {
|
||||
{
|
||||
A a;
|
||||
A b = std::move(a);
|
||||
a.foo();
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Object 'a' is moved}}
|
||||
// expected-warning@-3 {{Method called on moved-from object 'a'}}
|
||||
// expected-note@-4 {{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
A b = std::move(a); // peaceful-note {{Object 'a' is moved}}
|
||||
a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'a'}}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
A b = std::move(a);
|
||||
b = a;
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Object 'a' is moved}}
|
||||
// expected-warning@-3 {{Moved-from object 'a' is copied}}
|
||||
// expected-note@-4 {{Moved-from object 'a' is copied}}
|
||||
#endif
|
||||
A b = std::move(a); // peaceful-note {{Object 'a' is moved}}
|
||||
b = a; // peaceful-warning {{Moved-from object 'a' is copied}}
|
||||
// peaceful-note@-1 {{Moved-from object 'a' is copied}}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
A b = std::move(a);
|
||||
b = std::move(a);
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Object 'a' is moved}}
|
||||
// expected-warning@-3 {{Moved-from object 'a' is moved}}
|
||||
// expected-note@-4 {{Moved-from object 'a' is moved}}
|
||||
#endif
|
||||
A b = std::move(a); // peaceful-note {{Object 'a' is moved}}
|
||||
b = std::move(a); // peaceful-warning {{Moved-from object 'a' is moved}}
|
||||
// peaceful-note@-1 {{Moved-from object 'a' is moved}}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,35 +166,23 @@ void simpleMoveAssignementTest() {
|
|||
{
|
||||
A a;
|
||||
A b;
|
||||
b = std::move(a);
|
||||
a.foo();
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Object 'a' is moved}}
|
||||
// expected-warning@-3 {{Method called on moved-from object 'a'}}
|
||||
// expected-note@-4 {{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
b = std::move(a); // peaceful-note {{Object 'a' is moved}}
|
||||
a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'a'}}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
A b;
|
||||
b = std::move(a);
|
||||
A c(a);
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Object 'a' is moved}}
|
||||
// expected-warning@-3 {{Moved-from object 'a' is copied}}
|
||||
// expected-note@-4 {{Moved-from object 'a' is copied}}
|
||||
#endif
|
||||
b = std::move(a); // peaceful-note {{Object 'a' is moved}}
|
||||
A c(a); // peaceful-warning {{Moved-from object 'a' is copied}}
|
||||
// peaceful-note@-1 {{Moved-from object 'a' is copied}}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
A b;
|
||||
b = std::move(a);
|
||||
A c(std::move(a));
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Object 'a' is moved}}
|
||||
// expected-warning@-3 {{Moved-from object 'a' is moved}}
|
||||
// expected-note@-4 {{Moved-from object 'a' is moved}}
|
||||
#endif
|
||||
b = std::move(a); // peaceful-note {{Object 'a' is moved}}
|
||||
A c(std::move(a)); // peaceful-warning {{Moved-from object 'a' is moved}}
|
||||
// peaceful-note@-1 {{Moved-from object 'a' is moved}}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -212,13 +191,9 @@ void moveInInitListTest() {
|
|||
A a;
|
||||
};
|
||||
A a;
|
||||
S s{std::move(a)};
|
||||
a.foo();
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Object 'a' is moved}}
|
||||
// expected-warning@-3 {{Method called on moved-from object 'a'}}
|
||||
// expected-note@-4 {{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
S s{std::move(a)}; // peaceful-note {{Object 'a' is moved}}
|
||||
a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'a'}}
|
||||
}
|
||||
|
||||
// Don't report a bug if the variable was assigned to in the meantime.
|
||||
|
@ -232,43 +207,23 @@ void reinitializationTest(int i) {
|
|||
}
|
||||
{
|
||||
A a;
|
||||
if (i == 1) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Assuming 'i' is not equal to 1}}
|
||||
// expected-note@-3 {{Taking false branch}}
|
||||
// And the other report:
|
||||
// expected-note@-5 {{Assuming 'i' is not equal to 1}}
|
||||
// expected-note@-6 {{Taking false branch}}
|
||||
#endif
|
||||
if (i == 1) { // peaceful-note 2 {{Assuming 'i' is not equal to 1}}
|
||||
// peaceful-note@-1 2 {{Taking false branch}}
|
||||
A b;
|
||||
b = std::move(a);
|
||||
a = A();
|
||||
}
|
||||
if (i == 2) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Assuming 'i' is not equal to 2}}
|
||||
// expected-note@-3 {{Taking false branch}}
|
||||
// And the other report:
|
||||
// expected-note@-5 {{Assuming 'i' is not equal to 2}}
|
||||
// expected-note@-6 {{Taking false branch}}
|
||||
#endif
|
||||
if (i == 2) { // peaceful-note 2 {{Assuming 'i' is not equal to 2}}
|
||||
// peaceful-note@-1 2 {{Taking false branch}}
|
||||
a.foo(); // no-warning
|
||||
}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
if (i == 1) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Taking false branch}}
|
||||
// expected-note@-3 {{Taking false branch}}
|
||||
#endif
|
||||
if (i == 1) { // peaceful-note 2 {{Taking false branch}}
|
||||
std::move(a);
|
||||
}
|
||||
if (i == 2) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Taking false branch}}
|
||||
// expected-note@-3 {{Taking false branch}}
|
||||
#endif
|
||||
if (i == 2) { // peaceful-note 2 {{Taking false branch}}
|
||||
a = A();
|
||||
a.foo();
|
||||
}
|
||||
|
@ -286,36 +241,22 @@ void reinitializationTest(int i) {
|
|||
A b;
|
||||
b = std::move(a);
|
||||
a = A();
|
||||
b = std::move(a);
|
||||
a.foo();
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Object 'a' is moved}}
|
||||
// expected-warning@-3 {{Method called on moved-from object 'a'}}
|
||||
// expected-note@-4 {{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
b = std::move(a); // peaceful-note {{Object 'a' is moved}}
|
||||
a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'a'}}
|
||||
}
|
||||
// If a path exist where we not reinitialize the variable we report a bug.
|
||||
{
|
||||
A a;
|
||||
A b;
|
||||
b = std::move(a);
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Object 'a' is moved}}
|
||||
#endif
|
||||
if (i < 10) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Assuming 'i' is >= 10}}
|
||||
// expected-note@-3 {{Taking false branch}}
|
||||
#endif
|
||||
b = std::move(a); // peaceful-note {{Object 'a' is moved}}
|
||||
if (i < 10) { // peaceful-note {{Assuming 'i' is >= 10}}
|
||||
// peaceful-note@-1 {{Taking false branch}}
|
||||
a = A();
|
||||
}
|
||||
if (i > 5) {
|
||||
a.foo();
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Taking true branch}}
|
||||
// expected-warning@-3 {{Method called on moved-from object 'a'}}
|
||||
// expected-note@-4 {{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
if (i > 5) { // peaceful-note {{Taking true branch}}
|
||||
a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'a'}}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -330,117 +271,82 @@ void decltypeIsNotUseTest() {
|
|||
void loopTest() {
|
||||
{
|
||||
A a;
|
||||
for (int i = 0; i < bignum(); i++) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
#endif
|
||||
// FIXME: Execution doesn't jump to the end of the function yet.
|
||||
for (int i = 0; i < bignum(); i++) { // peaceful-note {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
rightRefCall(std::move(a)); // no-warning
|
||||
}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Loop condition is true. Entering loop body}}
|
||||
// expected-note@-3 {{Loop condition is true. Entering loop body}}
|
||||
// expected-note@-4 {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
#endif
|
||||
for (int i = 0; i < 2; i++) { // peaceful-note {{Loop condition is true. Entering loop body}}
|
||||
// peaceful-note@-1 {{Loop condition is true. Entering loop body}}
|
||||
// peaceful-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
rightRefCall(std::move(a)); // no-warning
|
||||
}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
for (int i = 0; i < bignum(); i++) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
#endif
|
||||
for (int i = 0; i < bignum(); i++) { // peaceful-note {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
leftRefCall(a); // no-warning
|
||||
}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Loop condition is true. Entering loop body}}
|
||||
// expected-note@-3 {{Loop condition is true. Entering loop body}}
|
||||
// expected-note@-4 {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
#endif
|
||||
for (int i = 0; i < 2; i++) { // peaceful-note {{Loop condition is true. Entering loop body}}
|
||||
// peaceful-note@-1 {{Loop condition is true. Entering loop body}}
|
||||
// peaceful-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
leftRefCall(a); // no-warning
|
||||
}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
for (int i = 0; i < bignum(); i++) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
#endif
|
||||
for (int i = 0; i < bignum(); i++) { // peaceful-note {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
constCopyOrMoveCall(a); // no-warning
|
||||
}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Loop condition is true. Entering loop body}}
|
||||
// expected-note@-3 {{Loop condition is true. Entering loop body}}
|
||||
// expected-note@-4 {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
#endif
|
||||
for (int i = 0; i < 2; i++) { // peaceful-note {{Loop condition is true. Entering loop body}}
|
||||
// peaceful-note@-1 {{Loop condition is true. Entering loop body}}
|
||||
// peaceful-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
constCopyOrMoveCall(a); // no-warning
|
||||
}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
for (int i = 0; i < bignum(); i++) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
#endif
|
||||
for (int i = 0; i < bignum(); i++) { // peaceful-note {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
moveInsideFunctionCall(a); // no-warning
|
||||
}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Loop condition is true. Entering loop body}}
|
||||
// expected-note@-3 {{Loop condition is true. Entering loop body}}
|
||||
// expected-note@-4 {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
#endif
|
||||
for (int i = 0; i < 2; i++) { // peaceful-note {{Loop condition is true. Entering loop body}}
|
||||
// peaceful-note@-1 {{Loop condition is true. Entering loop body}}
|
||||
// peaceful-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
moveInsideFunctionCall(a); // no-warning
|
||||
}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
for (int i = 0; i < bignum(); i++) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
#endif
|
||||
for (int i = 0; i < bignum(); i++) { // peaceful-note {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
copyOrMoveCall(a); // no-warning
|
||||
}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
for (int i = 0; i < 2; i++) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Loop condition is true. Entering loop body}}
|
||||
// expected-note@-3 {{Loop condition is true. Entering loop body}}
|
||||
// expected-note@-4 {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
#endif
|
||||
for (int i = 0; i < 2; i++) { // peaceful-note {{Loop condition is true. Entering loop body}}
|
||||
// peaceful-note@-1 {{Loop condition is true. Entering loop body}}
|
||||
// peaceful-note@-2 {{Loop condition is false. Execution jumps to the end of the function}}
|
||||
copyOrMoveCall(a); // no-warning
|
||||
}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
for (int i = 0; i < bignum(); i++) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Loop condition is true. Entering loop body}}
|
||||
// expected-note@-3 {{Loop condition is true. Entering loop body}}
|
||||
#endif
|
||||
constCopyOrMoveCall(std::move(a));
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Object 'a' is moved}}
|
||||
// expected-warning@-3 {{Moved-from object 'a' is moved}}
|
||||
// expected-note@-4 {{Moved-from object 'a' is moved}}
|
||||
#endif
|
||||
for (int i = 0; i < bignum(); i++) { // peaceful-note {{Loop condition is true. Entering loop body}}
|
||||
// peaceful-note@-1 {{Loop condition is true. Entering loop body}}
|
||||
constCopyOrMoveCall(std::move(a)); // peaceful-note {{Object 'a' is moved}}
|
||||
// peaceful-warning@-1 {{Moved-from object 'a' is moved}}
|
||||
// peaceful-note@-2 {{Moved-from object 'a' is moved}}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -462,17 +368,12 @@ void loopTest() {
|
|||
void uniqueTest(bool cond) {
|
||||
A a(42, 42.0);
|
||||
A b;
|
||||
b = std::move(a);
|
||||
b = std::move(a); // peaceful-note {{Object 'a' is moved}}
|
||||
|
||||
if (cond) {
|
||||
a.foo();
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-5 {{Object 'a' is moved}}
|
||||
// expected-note@-4 {{Assuming 'cond' is not equal to 0}}
|
||||
// expected-note@-5 {{Taking true branch}}
|
||||
// expected-warning@-5 {{Method called on moved-from object 'a'}}
|
||||
// expected-note@-6 {{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
if (cond) { // peaceful-note {{Assuming 'cond' is not equal to 0}}
|
||||
// peaceful-note@-1 {{Taking true branch}}
|
||||
a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'a'}}
|
||||
}
|
||||
if (cond) {
|
||||
a.bar(); // no-warning
|
||||
|
@ -483,13 +384,9 @@ void uniqueTest(bool cond) {
|
|||
|
||||
void uniqueTest2() {
|
||||
A a;
|
||||
A a1 = std::move(a);
|
||||
a.foo();
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Object 'a' is moved}}
|
||||
// expected-warning@-3 {{Method called on moved-from object 'a'}}
|
||||
// expected-note@-4 {{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
A a1 = std::move(a); // peaceful-note {{Object 'a' is moved}}
|
||||
a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'a'}}
|
||||
|
||||
A a2 = std::move(a); // no-warning
|
||||
a.foo(); // no-warning
|
||||
|
@ -499,19 +396,13 @@ void uniqueTest2() {
|
|||
//even on moved-from objects.
|
||||
void moveSafeFunctionsTest() {
|
||||
A a;
|
||||
A b = std::move(a);
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Object 'a' is moved}}
|
||||
#endif
|
||||
A b = std::move(a); // peaceful-note {{Object 'a' is moved}}
|
||||
a.empty(); // no-warning
|
||||
a.isEmpty(); // no-warning
|
||||
(void)a; // no-warning
|
||||
(bool)a; // expected-warning {{expression result unused}}
|
||||
a.foo();
|
||||
#ifndef PEACEFUL
|
||||
// expected-warning@-2 {{Method called on moved-from object 'a'}}
|
||||
// expected-note@-3 {{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'a'}}
|
||||
}
|
||||
|
||||
void moveStateResetFunctionsTest() {
|
||||
|
@ -589,51 +480,32 @@ class memberVariablesTest {
|
|||
|
||||
void f() {
|
||||
A b;
|
||||
b = std::move(a);
|
||||
a.foo();
|
||||
#ifdef AGGRESSIVE
|
||||
// expected-note@-3{{Object 'a' is moved}}
|
||||
// expected-warning@-3 {{Method called on moved-from object 'a'}}
|
||||
// expected-note@-4{{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
b = std::move(a); // aggressive-note {{Object 'a' is moved}}
|
||||
|
||||
b = std::move(static_a);
|
||||
static_a.foo();
|
||||
#ifdef AGGRESSIVE
|
||||
// expected-note@-3{{Object 'static_a' is moved}}
|
||||
// expected-warning@-3{{Method called on moved-from object 'static_a'}}
|
||||
// expected-note@-4{{Method called on moved-from object 'static_a'}}
|
||||
#endif
|
||||
a.foo(); // aggressive-warning {{Method called on moved-from object 'a'}}
|
||||
// aggressive-note@-1 {{Method called on moved-from object 'a'}}
|
||||
|
||||
b = std::move(static_a); // aggressive-note {{Object 'static_a' is moved}}
|
||||
static_a.foo(); // aggressive-warning {{Method called on moved-from object 'static_a'}}
|
||||
// aggressive-note@-1 {{Method called on moved-from object 'static_a'}}
|
||||
}
|
||||
};
|
||||
|
||||
void PtrAndArrayTest() {
|
||||
A *Ptr = new A(1, 1.5);
|
||||
A Arr[10];
|
||||
Arr[2] = std::move(*Ptr);
|
||||
(*Ptr).foo();
|
||||
#ifdef AGGRESSIVE
|
||||
// expected-note@-3{{Object is moved}}
|
||||
// expected-warning@-3{{Method called on moved-from object}}
|
||||
// expected-note@-4{{Method called on moved-from object}}
|
||||
#endif
|
||||
Arr[2] = std::move(*Ptr); // aggressive-note{{Object is moved}}
|
||||
(*Ptr).foo(); // aggressive-warning{{Method called on moved-from object}}
|
||||
// aggressive-note@-1{{Method called on moved-from object}}
|
||||
|
||||
Ptr = &Arr[1];
|
||||
Arr[3] = std::move(Arr[1]);
|
||||
Ptr->foo();
|
||||
#ifdef AGGRESSIVE
|
||||
// expected-note@-3{{Object is moved}}
|
||||
// expected-warning@-3{{Method called on moved-from object}}
|
||||
// expected-note@-4{{Method called on moved-from object}}
|
||||
#endif
|
||||
Arr[3] = std::move(Arr[1]); // aggressive-note {{Object is moved}}
|
||||
Ptr->foo(); // aggressive-warning {{Method called on moved-from object}}
|
||||
// aggressive-note@-1 {{Method called on moved-from object}}
|
||||
|
||||
Arr[3] = std::move(Arr[2]);
|
||||
Arr[2].foo();
|
||||
#ifdef AGGRESSIVE
|
||||
// expected-note@-3{{Object is moved}}
|
||||
// expected-warning@-3{{Method called on moved-from object}}
|
||||
// expected-note@-4{{Method called on moved-from object}}
|
||||
#endif
|
||||
Arr[3] = std::move(Arr[2]); // aggressive-note{{Object is moved}}
|
||||
Arr[2].foo(); // aggressive-warning{{Method called on moved-from object}}
|
||||
// aggressive-note@-1{{Method called on moved-from object}}
|
||||
|
||||
Arr[2] = std::move(Arr[3]); // reinitialization
|
||||
Arr[2].foo(); // no-warning
|
||||
|
@ -654,11 +526,8 @@ void differentBranchesTest(int i) {
|
|||
// Don't warn if the use is in a different branch from the move.
|
||||
{
|
||||
A a;
|
||||
if (i > 0) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Assuming 'i' is > 0}}
|
||||
// expected-note@-3 {{Taking true branch}}
|
||||
#endif
|
||||
if (i > 0) { // peaceful-note {{Assuming 'i' is > 0}}
|
||||
// peaceful-note@-1 {{Taking true branch}}
|
||||
A b;
|
||||
b = std::move(a);
|
||||
} else {
|
||||
|
@ -668,40 +537,28 @@ void differentBranchesTest(int i) {
|
|||
// Same thing, but with a ternary operator.
|
||||
{
|
||||
A a, b;
|
||||
i > 0 ? (void)(b = std::move(a)) : a.bar(); // no-warning
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{'?' condition is true}}
|
||||
#endif
|
||||
i > 0 ? (void)(b = std::move(a)) : a.bar(); // no-warning // peaceful-note {{'?' condition is true}}
|
||||
}
|
||||
// A variation on the theme above.
|
||||
{
|
||||
A a;
|
||||
a.foo() > 0 ? a.foo() : A(std::move(a)).foo();
|
||||
#ifdef DFS
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Assuming the condition is false}}
|
||||
// expected-note@-4 {{'?' condition is false}}
|
||||
#endif
|
||||
// peaceful-note@-2 {{Assuming the condition is false}}
|
||||
// peaceful-note@-3 {{'?' condition is false}}
|
||||
#else
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-8 {{Assuming the condition is true}}
|
||||
// expected-note@-9 {{'?' condition is true}}
|
||||
#endif
|
||||
// peaceful-note@-5 {{Assuming the condition is true}}
|
||||
// peaceful-note@-6 {{'?' condition is true}}
|
||||
#endif
|
||||
}
|
||||
// Same thing, but with a switch statement.
|
||||
{
|
||||
A a, b;
|
||||
switch (i) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Control jumps to 'case 1:'}}
|
||||
#endif
|
||||
switch (i) { // peaceful-note {{Control jumps to 'case 1:'}}
|
||||
case 1:
|
||||
b = std::move(a); // no-warning
|
||||
break;
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Execution jumps to the end of the function}}
|
||||
#endif
|
||||
// FIXME: Execution doesn't jump to the end of the function yet.
|
||||
break; // peaceful-note {{Execution jumps to the end of the function}}
|
||||
case 2:
|
||||
a.foo(); // no-warning
|
||||
break;
|
||||
|
@ -710,21 +567,12 @@ void differentBranchesTest(int i) {
|
|||
// However, if there's a fallthrough, we do warn.
|
||||
{
|
||||
A a, b;
|
||||
switch (i) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Control jumps to 'case 1:'}}
|
||||
#endif
|
||||
switch (i) { // peaceful-note {{Control jumps to 'case 1:'}}
|
||||
case 1:
|
||||
b = std::move(a);
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Object 'a' is moved}}
|
||||
#endif
|
||||
b = std::move(a); // peaceful-note {{Object 'a' is moved}}
|
||||
case 2:
|
||||
a.foo();
|
||||
#ifndef PEACEFUL
|
||||
// expected-warning@-2 {{Method called on moved-from object}}
|
||||
// expected-note@-3 {{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'a'}}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -739,22 +587,15 @@ void tempTest() {
|
|||
}
|
||||
|
||||
void interFunTest1(A &a) {
|
||||
a.bar();
|
||||
#ifndef PEACEFUL
|
||||
// expected-warning@-2 {{Method called on moved-from object 'a'}}
|
||||
// expected-note@-3 {{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
a.bar(); // peaceful-warning {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'a'}}
|
||||
}
|
||||
|
||||
void interFunTest2() {
|
||||
A a;
|
||||
A b;
|
||||
b = std::move(a);
|
||||
interFunTest1(a);
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Object 'a' is moved}}
|
||||
// expected-note@-3 {{Calling 'interFunTest1'}}
|
||||
#endif
|
||||
b = std::move(a); // peaceful-note {{Object 'a' is moved}}
|
||||
interFunTest1(a); // peaceful-note {{Calling 'interFunTest1'}}
|
||||
}
|
||||
|
||||
void foobar(A a, int i);
|
||||
|
@ -762,12 +603,9 @@ void foobar(int i, A a);
|
|||
|
||||
void paramEvaluateOrderTest() {
|
||||
A a;
|
||||
foobar(std::move(a), a.getI());
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Object 'a' is moved}}
|
||||
// expected-warning@-3 {{Method called on moved-from object 'a'}}
|
||||
// expected-note@-4 {{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
foobar(std::move(a), a.getI()); // peaceful-note {{Object 'a' is moved}}
|
||||
// peaceful-warning@-1 {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-2 {{Method called on moved-from object 'a'}}
|
||||
|
||||
//FALSE NEGATIVE since parameters evaluate order is undefined
|
||||
foobar(a.getI(), std::move(a)); //no-warning
|
||||
|
@ -790,14 +628,10 @@ void regionAndPointerEscapeTest() {
|
|||
{
|
||||
A a;
|
||||
A b;
|
||||
b = std::move(a);
|
||||
b = std::move(a); // peaceful-note{{Object 'a' is moved}}
|
||||
not_known_pass_by_const_ref(a);
|
||||
a.foo();
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-4{{Object 'a' is moved}}
|
||||
// expected-warning@-3{{Method called on moved-from object 'a'}}
|
||||
// expected-note@-4 {{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'a'}}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
|
@ -816,14 +650,10 @@ void regionAndPointerEscapeTest() {
|
|||
{
|
||||
A a;
|
||||
A b;
|
||||
b = std::move(a);
|
||||
b = std::move(a); // peaceful-note {{Object 'a' is moved}}
|
||||
not_known_pass_by_const_ptr(&a);
|
||||
a.foo();
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-4{{Object 'a' is moved}}
|
||||
// expected-warning@-3{{Method called on moved-from object 'a'}}
|
||||
// expected-note@-4 {{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'a'}}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -836,12 +666,9 @@ void declarationSequenceTest() {
|
|||
}
|
||||
{
|
||||
A a;
|
||||
A a1 = std::move(a), a2 = a;
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Object 'a' is moved}}
|
||||
// expected-warning@-3 {{Moved-from object 'a' is copied}}
|
||||
// expected-note@-4 {{Moved-from object 'a' is copied}}
|
||||
#endif
|
||||
A a1 = std::move(a), a2 = a; // peaceful-note {{Object 'a' is moved}}
|
||||
// peaceful-warning@-1 {{Moved-from object 'a' is copied}}
|
||||
// peaceful-note@-2 {{Moved-from object 'a' is copied}}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -849,74 +676,59 @@ void declarationSequenceTest() {
|
|||
void logicalOperatorsSequenceTest() {
|
||||
{
|
||||
A a;
|
||||
if (a.foo() > 0 && A(std::move(a)).foo() > 0) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Assuming the condition is false}}
|
||||
// expected-note@-3 {{Left side of '&&' is false}}
|
||||
// expected-note@-4 {{Taking false branch}}
|
||||
// And the other report:
|
||||
// expected-note@-6 {{Assuming the condition is false}}
|
||||
// expected-note@-7 {{Left side of '&&' is false}}
|
||||
// expected-note@-8 {{Taking false branch}}
|
||||
if (a.foo() > 0 && A(std::move(a)).foo() > 0) { // peaceful-note {{Assuming the condition is false}}
|
||||
// peaceful-note@-1 {{Left side of '&&' is false}}
|
||||
// peaceful-note@-2 {{Taking false branch}}
|
||||
// And the other report:
|
||||
// peaceful-note@-4 {{Assuming the condition is false}}
|
||||
// peaceful-note@-5 {{Left side of '&&' is false}}
|
||||
// peaceful-note@-6 {{Taking false branch}}
|
||||
A().bar();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
// A variation: Negate the result of the && (which pushes the && further down
|
||||
// into the AST).
|
||||
{
|
||||
A a;
|
||||
if (!(a.foo() > 0 && A(std::move(a)).foo() > 0)) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Assuming the condition is false}}
|
||||
// expected-note@-3 {{Left side of '&&' is false}}
|
||||
// expected-note@-4 {{Taking true branch}}
|
||||
// And the other report:
|
||||
// expected-note@-6 {{Assuming the condition is false}}
|
||||
// expected-note@-7 {{Left side of '&&' is false}}
|
||||
// expected-note@-8 {{Taking true branch}}
|
||||
#endif
|
||||
if (!(a.foo() > 0 && A(std::move(a)).foo() > 0)) { // peaceful-note {{Assuming the condition is false}}
|
||||
// peaceful-note@-1 {{Left side of '&&' is false}}
|
||||
// peaceful-note@-2 {{Taking true branch}}
|
||||
// And the other report:
|
||||
// peaceful-note@-4 {{Assuming the condition is false}}
|
||||
// peaceful-note@-5 {{Left side of '&&' is false}}
|
||||
// peaceful-note@-6 {{Taking true branch}}
|
||||
A().bar();
|
||||
}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
if (A(std::move(a)).foo() > 0 && a.foo() > 0) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Object 'a' is moved}}
|
||||
// expected-note@-3 {{Assuming the condition is true}}
|
||||
// expected-note@-4 {{Left side of '&&' is true}}
|
||||
// expected-warning@-5 {{Method called on moved-from object 'a'}}
|
||||
// expected-note@-6 {{Method called on moved-from object 'a'}}
|
||||
// And the other report:
|
||||
// expected-note@-8 {{Assuming the condition is false}}
|
||||
// expected-note@-9 {{Left side of '&&' is false}}
|
||||
// expected-note@-10{{Taking false branch}}
|
||||
#endif
|
||||
if (A(std::move(a)).foo() > 0 && a.foo() > 0) { // peaceful-note {{Object 'a' is moved}}
|
||||
// peaceful-note@-1 {{Assuming the condition is true}}
|
||||
// peaceful-note@-2 {{Left side of '&&' is true}}
|
||||
// peaceful-warning@-3 {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-4 {{Method called on moved-from object 'a'}}
|
||||
// And the other report:
|
||||
// peaceful-note@-6 {{Assuming the condition is false}}
|
||||
// peaceful-note@-7 {{Left side of '&&' is false}}
|
||||
// peaceful-note@-8 {{Taking false branch}}
|
||||
A().bar();
|
||||
}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
if (a.foo() > 0 || A(std::move(a)).foo() > 0) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Assuming the condition is true}}
|
||||
// expected-note@-3 {{Left side of '||' is true}}
|
||||
// expected-note@-4 {{Taking true branch}}
|
||||
#endif
|
||||
if (a.foo() > 0 || A(std::move(a)).foo() > 0) { // peaceful-note {{Assuming the condition is true}}
|
||||
// peaceful-note@-1 {{Left side of '||' is true}}
|
||||
// peaceful-note@-2 {{Taking true branch}}
|
||||
A().bar();
|
||||
}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
if (A(std::move(a)).foo() > 0 || a.foo() > 0) {
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-2 {{Object 'a' is moved}}
|
||||
// expected-note@-3 {{Assuming the condition is false}}
|
||||
// expected-note@-4 {{Left side of '||' is false}}
|
||||
// expected-warning@-5 {{Method called on moved-from object 'a'}}
|
||||
// expected-note@-6 {{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
if (A(std::move(a)).foo() > 0 || a.foo() > 0) { // peaceful-note {{Object 'a' is moved}}
|
||||
// peaceful-note@-1 {{Assuming the condition is false}}
|
||||
// peaceful-note@-2 {{Left side of '||' is false}}
|
||||
// peaceful-warning@-3 {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-4 {{Method called on moved-from object 'a'}}
|
||||
A().bar();
|
||||
}
|
||||
}
|
||||
|
@ -950,47 +762,31 @@ struct C : public A {
|
|||
void subRegionMoveTest() {
|
||||
{
|
||||
A a;
|
||||
B b = std::move(a.b);
|
||||
a.b.foo();
|
||||
#ifdef AGGRESSIVE
|
||||
// expected-note@-3{{Object 'b' is moved}}
|
||||
// expected-warning@-3{{Method called on moved-from object 'b'}}
|
||||
// expected-note@-4 {{Method called on moved-from object 'b'}}
|
||||
#endif
|
||||
B b = std::move(a.b); // aggressive-note {{Object 'b' is moved}}
|
||||
a.b.foo(); // aggressive-warning {{Method called on moved-from object 'b'}}
|
||||
// aggressive-note@-1 {{Method called on moved-from object 'b'}}
|
||||
}
|
||||
{
|
||||
A a;
|
||||
A a1 = std::move(a);
|
||||
a.b.foo();
|
||||
#ifdef AGGRESSIVE
|
||||
// expected-note@-3{{Calling move constructor for 'A'}}
|
||||
// expected-note@-4{{Returning from move constructor for 'A'}}
|
||||
// expected-warning@-4{{Method called on moved-from object 'b'}}
|
||||
// expected-note@-5{{Method called on moved-from object 'b'}}
|
||||
#endif
|
||||
A a1 = std::move(a); // aggressive-note {{Calling move constructor for 'A'}}
|
||||
// aggressive-note@-1 {{Returning from move constructor for 'A'}}
|
||||
a.b.foo(); // aggressive-warning{{Method called on moved-from object 'b'}}
|
||||
// aggressive-note@-1{{Method called on moved-from object 'b'}}
|
||||
}
|
||||
// Don't report a misuse if any SuperRegion is already reported.
|
||||
{
|
||||
A a;
|
||||
A a1 = std::move(a);
|
||||
a.foo();
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Object 'a' is moved}}
|
||||
// expected-warning@-3 {{Method called on moved-from object 'a'}}
|
||||
// expected-note@-4 {{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
a.b.foo(); // no-warning
|
||||
A a1 = std::move(a); // peaceful-note {{Object 'a' is moved}}
|
||||
a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'a'}}
|
||||
a.b.foo(); // no-warning
|
||||
}
|
||||
{
|
||||
C c;
|
||||
C c1 = std::move(c);
|
||||
c.foo();
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Object 'c' is moved}}
|
||||
// expected-warning@-3 {{Method called on moved-from object 'c'}}
|
||||
// expected-note@-4 {{Method called on moved-from object 'c'}}
|
||||
#endif
|
||||
c.b.foo(); // no-warning
|
||||
C c1 = std::move(c); // peaceful-note {{Object 'c' is moved}}
|
||||
c.foo(); // peaceful-warning {{Method called on moved-from object 'c'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'c'}}
|
||||
c.b.foo(); // no-warning
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1010,14 +806,10 @@ void resetSuperClass2() {
|
|||
|
||||
void reportSuperClass() {
|
||||
C c;
|
||||
C c1 = std::move(c);
|
||||
c.foo();
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Object 'c' is moved}}
|
||||
// expected-warning@-3 {{Method called on moved-from object 'c'}}
|
||||
// expected-note@-4 {{Method called on moved-from object 'c'}}
|
||||
#endif
|
||||
C c2 = c; // no-warning
|
||||
C c1 = std::move(c); // peaceful-note {{Object 'c' is moved}}
|
||||
c.foo(); // peaceful-warning {{Method called on moved-from object 'c'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'c'}}
|
||||
C c2 = c; // no-warning
|
||||
}
|
||||
|
||||
struct Empty {};
|
||||
|
@ -1098,31 +890,24 @@ class HasSTLField {
|
|||
void testVector() {
|
||||
// Warn even in non-aggressive mode when it comes to STL, because
|
||||
// in STL the object is left in "valid but unspecified state" after move.
|
||||
std::vector<int> W = std::move(V); // expected-note{{Object 'V' of type 'std::vector' is left in a valid but unspecified state after move}}
|
||||
V.push_back(123); // expected-warning{{Method called on moved-from object 'V'}}
|
||||
// expected-note@-1{{Method called on moved-from object 'V'}}
|
||||
std::vector<int> W = std::move(V); // expected-note {{Object 'V' of type 'std::vector' is left in a valid but unspecified state after move}}
|
||||
V.push_back(123); // expected-warning {{Method called on moved-from object 'V'}}
|
||||
// expected-note@-1 {{Method called on moved-from object 'V'}}
|
||||
}
|
||||
|
||||
std::unique_ptr<int> P;
|
||||
void testUniquePtr() {
|
||||
// unique_ptr remains in a well-defined state after move.
|
||||
std::unique_ptr<int> Q = std::move(P);
|
||||
P.get();
|
||||
#ifdef AGGRESSIVE
|
||||
// expected-warning@-2{{Method called on moved-from object 'P'}}
|
||||
// expected-note@-4{{Object 'P' is moved}}
|
||||
// expected-note@-4{{Method called on moved-from object 'P'}}
|
||||
#endif
|
||||
std::unique_ptr<int> Q = std::move(P); // aggressive-note {{Object 'P' is moved}}
|
||||
// non-aggressive-note@-1 {{Smart pointer 'P' of type 'std::unique_ptr' is reset to null when moved from}}
|
||||
P.get(); // aggressive-warning{{Method called on moved-from object 'P'}}
|
||||
// aggressive-note@-1{{Method called on moved-from object 'P'}}
|
||||
|
||||
// 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
|
||||
*P += 1; // non-aggressive-warning{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}}
|
||||
// non-aggressive-note@-1{{Dereference of null smart pointer 'P' of type 'std::unique_ptr'}}
|
||||
|
||||
// The program should have crashed by now.
|
||||
clang_analyzer_warnIfReached(); // no-warning
|
||||
|
@ -1130,25 +915,17 @@ class HasSTLField {
|
|||
};
|
||||
|
||||
void localRValueMove(A &&a) {
|
||||
A b = std::move(a);
|
||||
a.foo();
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Object 'a' is moved}}
|
||||
// expected-warning@-3 {{Method called on moved-from object 'a'}}
|
||||
// expected-note@-4 {{Method called on moved-from object 'a'}}
|
||||
#endif
|
||||
A b = std::move(a); // peaceful-note {{Object 'a' is moved}}
|
||||
a.foo(); // peaceful-warning {{Method called on moved-from object 'a'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'a'}}
|
||||
}
|
||||
|
||||
void localUniquePtr(std::unique_ptr<int> P) {
|
||||
// Even though unique_ptr is safe to use after move,
|
||||
// reusing a local variable this way usually indicates a bug.
|
||||
std::unique_ptr<int> Q = std::move(P);
|
||||
P.get();
|
||||
#ifndef PEACEFUL
|
||||
// expected-note@-3 {{Object 'P' is moved}}
|
||||
// expected-warning@-3 {{Method called on moved-from object 'P'}}
|
||||
// expected-note@-4 {{Method called on moved-from object 'P'}}
|
||||
#endif
|
||||
std::unique_ptr<int> Q = std::move(P); // peaceful-note {{Object 'P' is moved}}
|
||||
P.get(); // peaceful-warning {{Method called on moved-from object 'P'}}
|
||||
// peaceful-note@-1 {{Method called on moved-from object 'P'}}
|
||||
}
|
||||
|
||||
void localUniquePtrWithArrow(std::unique_ptr<A> P) {
|
||||
|
|
Loading…
Reference in New Issue