summaryrefslogtreecommitdiffstats
path: root/clang/test/Analysis/temporaries.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/test/Analysis/temporaries.cpp')
-rw-r--r--clang/test/Analysis/temporaries.cpp173
1 files changed, 11 insertions, 162 deletions
diff --git a/clang/test/Analysis/temporaries.cpp b/clang/test/Analysis/temporaries.cpp
index 0cc90880f44..c57d984a1dc 100644
--- a/clang/test/Analysis/temporaries.cpp
+++ b/clang/test/Analysis/temporaries.cpp
@@ -1,9 +1,8 @@
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++03 %s
// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -verify -w -std=c++11 %s
-// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -DTEMPORARY_DTORS -verify -w -analyzer-config cfg-temporary-dtors=true %s -std=c++11
+// RUN: %clang_cc1 -analyze -analyzer-checker=core,debug.ExprInspection -DTEMPORARY_DTORS -verify -w -analyzer-config cfg-temporary-dtors=true %s
extern bool clang_analyzer_eval(bool);
-extern bool clang_analyzer_warnIfReached();
struct Trivial {
Trivial(int x) : value(x) {}
@@ -112,13 +111,13 @@ namespace compound_literals {
}
namespace destructors {
- struct Dtor {
- ~Dtor();
- };
- extern bool coin();
- extern bool check(const Dtor &);
-
void testPR16664andPR18159Crash() {
+ struct Dtor {
+ ~Dtor();
+ };
+ extern bool coin();
+ extern bool check(const Dtor &);
+
// Regression test: we used to assert here when tmp dtors are enabled.
// PR16664 and PR18159
if (coin() && (coin() || coin() || check(Dtor()))) {
@@ -194,7 +193,8 @@ namespace destructors {
(i == 4 || i == 4 ||
compute(i == 5 && (i == 4 || check(NoReturnDtor()))))) ||
i != 4) {
- clang_analyzer_eval(true); // no warning, unreachable code
+ // FIXME: This shouldn't cause a warning.
+ clang_analyzer_eval(true); // expected-warning{{TRUE}}
}
}
@@ -211,7 +211,8 @@ namespace destructors {
void testConsistencyNestedComplex(bool value) {
if (value) {
if (!value || !value || check(NoReturnDtor())) {
- clang_analyzer_eval(true); // no warning, unreachable code
+ // FIXME: This shouldn't cause a warning.
+ clang_analyzer_eval(true); // expected-warning{{TRUE}}
}
}
}
@@ -224,112 +225,6 @@ namespace destructors {
}
}
}
- // PR16664 and PR18159
- void testConsistencyNestedComplexMidBranch(bool value) {
- if (value) {
- if (!value || !value || check(NoReturnDtor()) || value) {
- clang_analyzer_eval(true); // no warning, unreachable code
- }
- }
- }
-
- // PR16664 and PR18159
- void testConsistencyNestedComplexNestedBranch(bool value) {
- if (value) {
- if (!value || (!value || check(NoReturnDtor()) || value)) {
- clang_analyzer_eval(true); // no warning, unreachable code
- }
- }
- }
-
- // PR16664 and PR18159
- void testConsistencyNestedVariableModification(bool value) {
- bool other = true;
- if (value) {
- if (!other || !value || (other = false) || check(NoReturnDtor()) ||
- !other) {
- clang_analyzer_eval(true); // no warning, unreachable code
- }
- }
- }
-
- void testTernaryNoReturnTrueBranch(bool value) {
- if (value) {
- bool b = value && value ? check(NoReturnDtor()) : true;
- clang_analyzer_eval(true); // no warning, unreachable code
- }
- }
- void testTernaryNoReturnFalseBranch(bool value) {
- if (value) {
- bool b = !value && !value ? true : check(NoReturnDtor());
- clang_analyzer_eval(true); // no warning, unreachable code
- }
- }
- void testTernaryIgnoreNoreturnBranch(bool value) {
- if (value) {
- bool b = !value && !value ? check(NoReturnDtor()) : true;
- clang_analyzer_eval(true); // expected-warning{{TRUE}}
- }
- }
-
- void testLoop() {
- for (int i = 0; i < 10; ++i) {
- if (i < 3 && (i >= 2 || check(NoReturnDtor()))) {
- clang_analyzer_eval(true); // no warning, unreachable code
- }
- }
- }
-
- bool testRecursiveFrames(bool isInner) {
- if (isInner ||
- (clang_analyzer_warnIfReached(), false) || // expected-warning{{REACHABLE}}
- check(NoReturnDtor()) ||
- testRecursiveFrames(true)) {
- clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
- }
- }
- void testRecursiveFramesStart() { testRecursiveFrames(false); }
-
- void testLambdas() {
- // This is the test we would like to write:
- // []() { check(NoReturnDtor()); } != nullptr || check(Dtor());
- // But currently the analyzer stops when it encounters a lambda:
- [] {};
- // The CFG for this now looks correct, but we still do not reach the line
- // below.
- clang_analyzer_warnIfReached(); // FIXME: Should warn.
- }
-
- void testGnuExpressionStatements(int v) {
- ({ ++v; v == 10 || check(NoReturnDtor()); v == 42; }) || v == 23;
- clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
-
- ({ ++v; check(NoReturnDtor()); v == 42; }) || v == 23;
- clang_analyzer_warnIfReached(); // no warning, unreachable code
- }
-
- void testGnuExpressionStatementsDestructionPoint(int v) {
- // In normal context, the temporary destructor runs at the end of the full
- // statement, thus the last statement is reached.
- (++v, check(NoReturnDtor()), v == 42),
- clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
-
- // GNU expression statements execute temporary destructors within the
- // blocks, thus the last statement is not reached.
- ({ ++v; check(NoReturnDtor()); v == 42; }),
- clang_analyzer_warnIfReached(); // no warning, unreachable code
- }
-
- void testMultipleTemporaries(bool value) {
- if (value) {
- // FIXME: Find a way to verify construction order.
- // ~Dtor should run before ~NoReturnDtor() because construction order is
- // guaranteed by comma operator.
- if (!value || check((NoReturnDtor(), Dtor())) || value) {
- clang_analyzer_eval(true); // no warning, unreachable code
- }
- }
- }
void testBinaryOperatorShortcut(bool value) {
if (value) {
@@ -339,52 +234,6 @@ namespace destructors {
}
}
- void testIfAtEndOfLoop() {
- int y = 0;
- while (true) {
- if (y > 0) {
- clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
- }
- ++y;
- // Test that the CFG gets hooked up correctly when temporary destructors
- // are handled after a statically known branch condition.
- if (true) (void)0; else (void)check(NoReturnDtor());
- }
- }
-
- void testTernaryAtEndOfLoop() {
- int y = 0;
- while (true) {
- if (y > 0) {
- clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
- }
- ++y;
- // Test that the CFG gets hooked up correctly when temporary destructors
- // are handled after a statically known branch condition.
- true ? (void)0 : (void)check(NoReturnDtor());
- }
- }
-
- void testNoReturnInComplexCondition() {
- check(Dtor()) &&
- (check(NoReturnDtor()) || check(NoReturnDtor())) && check(Dtor());
- clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
- }
-
- void testSequencingOfConditionalTempDtors(bool b) {
- b || (check(Dtor()), check(NoReturnDtor()));
- clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
- }
-
- void testSequencingOfConditionalTempDtors2(bool b) {
- (b || check(Dtor())), check(NoReturnDtor());
- clang_analyzer_warnIfReached(); // no warning, unreachable code
- }
-
- void testSequencingOfConditionalTempDtorsWithinBinaryOperators(bool b) {
- b || (check(Dtor()) + check(NoReturnDtor()));
- clang_analyzer_warnIfReached(); // expected-warning{{REACHABLE}}
- }
#endif // TEMPORARY_DTORS
}
OpenPOWER on IntegriCloud