summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2014-04-29 01:56:12 +0000
committerJordan Rose <jordan_rose@apple.com>2014-04-29 01:56:12 +0000
commitbcd889730d4b516dfbd6e206d06280c91cfa076c (patch)
treedbd90a0e43ba9f5a22834140f7efb87201b25661 /clang
parentcf37110920cb1cc801ea8502fa05cb12aee388c0 (diff)
downloadbcm5719-llvm-bcd889730d4b516dfbd6e206d06280c91cfa076c.tar.gz
bcm5719-llvm-bcd889730d4b516dfbd6e206d06280c91cfa076c.zip
[analyzer] Don't crash when a construction is followed by an uninitialized variable.
This could happen due to unfortunate CFG coincidences. PR19579 llvm-svn: 207486
Diffstat (limited to 'clang')
-rw-r--r--clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp2
-rw-r--r--clang/test/Analysis/ctor.mm27
2 files changed, 28 insertions, 1 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
index e1eb7281479..4251cdc7293 100644
--- a/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
+++ b/clang/lib/StaticAnalyzer/Core/ExprEngineCXX.cpp
@@ -128,7 +128,7 @@ static const MemRegion *getRegionForConstructedObject(
if (Optional<CFGStmt> StmtElem = Next.getAs<CFGStmt>()) {
if (const DeclStmt *DS = dyn_cast<DeclStmt>(StmtElem->getStmt())) {
if (const VarDecl *Var = dyn_cast<VarDecl>(DS->getSingleDecl())) {
- if (Var->getInit()->IgnoreImplicit() == CE) {
+ if (Var->getInit() && Var->getInit()->IgnoreImplicit() == CE) {
SVal LValue = State->getLValue(Var, LCtx);
QualType Ty = Var->getType();
LValue = makeZeroElementRegion(State, LValue, Ty);
diff --git a/clang/test/Analysis/ctor.mm b/clang/test/Analysis/ctor.mm
index 77c87905e1f..58db91e64d0 100644
--- a/clang/test/Analysis/ctor.mm
+++ b/clang/test/Analysis/ctor.mm
@@ -674,3 +674,30 @@ namespace InitializerList {
clang_analyzer_eval(list->usedInitializerList); // expected-warning{{UNKNOWN}}
}
}
+
+namespace PR19579 {
+ class C {};
+
+ struct S {
+ C c;
+ int i;
+ };
+
+ void f() {
+ C();
+ int a;
+ }
+
+ void g() {
+ // This order triggers the initialization of the inner "a" after the
+ // constructor for "C" is run, which used to confuse the analyzer
+ // (is "C()" the initialization of "a"?).
+ struct S s = {
+ C(),
+ ({
+ int a, b = 0;
+ 0;
+ })
+ };
+ }
+}
OpenPOWER on IntegriCloud