Hi jordan_rose,
after flipping cfg-temporary-destructors to true, I noticed an assertion failure
in ExprEngine when processing complex conditional expressions. Apparently, the
produced CFG were no longer of the form the function was expecting. Simply
removing the assertion allows the analyzer to continue, and I notice no further
regressions resulting from the change. I added tests to verify that conditions
are still handled correctly.
http://llvm-reviews.chandlerc.com/D1186
Files:
lib/StaticAnalyzer/Core/ExprEngine.cpp
test/Analysis/temporaries.cpp
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1323,8 +1323,6 @@
return Condition;
}
- assert(I != E);
-
while (Condition) {
BO = dyn_cast<BinaryOperator>(Condition);
if (!BO || !BO->isLogicalOp())
Index: test/Analysis/temporaries.cpp
===================================================================
--- test/Analysis/temporaries.cpp
+++ test/Analysis/temporaries.cpp
@@ -125,3 +125,30 @@
clang_analyzer_eval(threadDirectRef.value == 42); // expected-warning{{TRUE}}
#endif
}
+
+namespace branching {
+ // the following code used to produce an assertion failure in
+ // ExprEngine.cpp, in ResolveCondition()
+ void fn() { 1 && ((0 && 0) || (NonTrivial(1), 1)); }
+
+ // after fixing, make sure conditions are still evaluated as expected
+ bool unknown();
+ bool id(bool x, bool &a) { a = x; return x; }
+ bool neg(bool x, bool &a) { a = x; return !x; }
+
+ void fn1(bool x) {
+ bool a1, a2, a3, a4;
+ a1 = a2 = a3 = a4 = unknown();
+ if (neg(x, a1) && ((id(x, a2) && id(x, a3)) || (NonTrivial(1), neg(x,
a4)))) {
+ clang_analyzer_eval(a1); // expected-warning{{FALSE}}
+ clang_analyzer_eval(a2); // expected-warning{{FALSE}}
+ clang_analyzer_eval(a3); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a4); // expected-warning{{FALSE}}
+ } else {
+ clang_analyzer_eval(a1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a2); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a3); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a4); // expected-warning{{UNKNOWN}}
+ }
+ }
+}
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1323,8 +1323,6 @@
return Condition;
}
- assert(I != E);
-
while (Condition) {
BO = dyn_cast<BinaryOperator>(Condition);
if (!BO || !BO->isLogicalOp())
Index: test/Analysis/temporaries.cpp
===================================================================
--- test/Analysis/temporaries.cpp
+++ test/Analysis/temporaries.cpp
@@ -125,3 +125,30 @@
clang_analyzer_eval(threadDirectRef.value == 42); // expected-warning{{TRUE}}
#endif
}
+
+namespace branching {
+ // the following code used to produce an assertion failure in
+ // ExprEngine.cpp, in ResolveCondition()
+ void fn() { 1 && ((0 && 0) || (NonTrivial(1), 1)); }
+
+ // after fixing, make sure conditions are still evaluated as expected
+ bool unknown();
+ bool id(bool x, bool &a) { a = x; return x; }
+ bool neg(bool x, bool &a) { a = x; return !x; }
+
+ void fn1(bool x) {
+ bool a1, a2, a3, a4;
+ a1 = a2 = a3 = a4 = unknown();
+ if (neg(x, a1) && ((id(x, a2) && id(x, a3)) || (NonTrivial(1), neg(x, a4)))) {
+ clang_analyzer_eval(a1); // expected-warning{{FALSE}}
+ clang_analyzer_eval(a2); // expected-warning{{FALSE}}
+ clang_analyzer_eval(a3); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a4); // expected-warning{{FALSE}}
+ } else {
+ clang_analyzer_eval(a1); // expected-warning{{TRUE}}
+ clang_analyzer_eval(a2); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a3); // expected-warning{{UNKNOWN}}
+ clang_analyzer_eval(a4); // expected-warning{{UNKNOWN}}
+ }
+ }
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits