summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAnna Zaks <ganna@apple.com>2015-11-19 01:25:28 +0000
committerAnna Zaks <ganna@apple.com>2015-11-19 01:25:28 +0000
commit61fcb521fa1dd3426b653818fd315f9e542fc12b (patch)
treeda1af4fce920f1a4b194c405e81651273db3d56d
parentd4129b47d0bc780d448532c1bbfe51280ea4d8ef (diff)
downloadbcm5719-llvm-61fcb521fa1dd3426b653818fd315f9e542fc12b.tar.gz
bcm5719-llvm-61fcb521fa1dd3426b653818fd315f9e542fc12b.zip
[analyzer] Improve modeling of static initializers.
Conversions between unrelated pointer types (e.g. char * and void *) involve bitcasts which were not properly modeled in case of static initializers. The patch fixes this problem. The problem was originally spotted by Artem Dergachev. Patched by Yuri Gribov! Differential Revision: http://reviews.llvm.org/D14652 llvm-svn: 253532
-rw-r--r--clang/lib/StaticAnalyzer/Core/SValBuilder.cpp14
-rw-r--r--clang/test/Analysis/inline.cpp9
2 files changed, 18 insertions, 5 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
index 4f8ccd0329d..98fac33c22a 100644
--- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -275,11 +275,17 @@ Optional<SVal> SValBuilder::getConstantVal(const Expr *E) {
case Stmt::ImplicitCastExprClass: {
const CastExpr *CE = cast<CastExpr>(E);
- if (CE->getCastKind() == CK_ArrayToPointerDecay) {
- Optional<SVal> ArrayVal = getConstantVal(CE->getSubExpr());
- if (!ArrayVal)
+ switch (CE->getCastKind()) {
+ default:
+ break;
+ case CK_ArrayToPointerDecay:
+ case CK_BitCast: {
+ const Expr *SE = CE->getSubExpr();
+ Optional<SVal> Val = getConstantVal(SE);
+ if (!Val)
return None;
- return evalCast(*ArrayVal, CE->getType(), CE->getSubExpr()->getType());
+ return evalCast(*Val, CE->getType(), SE->getType());
+ }
}
// FALLTHROUGH
}
diff --git a/clang/test/Analysis/inline.cpp b/clang/test/Analysis/inline.cpp
index 183df16e124..b7962b53a89 100644
--- a/clang/test/Analysis/inline.cpp
+++ b/clang/test/Analysis/inline.cpp
@@ -275,7 +275,7 @@ namespace DefaultArgs {
clang_analyzer_eval(defaultReferenceZero(1) == -1); // expected-warning{{TRUE}}
clang_analyzer_eval(defaultReferenceZero() == 0); // expected-warning{{TRUE}}
-}
+ }
double defaultFloatReference(const double &i = 42) {
return -i;
@@ -300,6 +300,13 @@ namespace DefaultArgs {
clang_analyzer_eval(defaultString("xyz") == 'y'); // expected-warning{{TRUE}}
clang_analyzer_eval(defaultString() == 'b'); // expected-warning{{TRUE}}
}
+
+ const void * const void_string = "abc";
+
+ void testBitcastedString() {
+ clang_analyzer_eval(0 != void_string); // expected-warning{{TRUE}}
+ clang_analyzer_eval('b' == ((char *)void_string)[1]); // expected-warning{{TRUE}}
+ }
}
namespace OperatorNew {
OpenPOWER on IntegriCloud