diff options
author | Jordan Rose <jordan_rose@apple.com> | 2014-04-29 01:56:12 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2014-04-29 01:56:12 +0000 |
commit | bcd889730d4b516dfbd6e206d06280c91cfa076c (patch) | |
tree | dbd90a0e43ba9f5a22834140f7efb87201b25661 /clang | |
parent | cf37110920cb1cc801ea8502fa05cb12aee388c0 (diff) | |
download | bcm5719-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.cpp | 2 | ||||
-rw-r--r-- | clang/test/Analysis/ctor.mm | 27 |
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; + }) + }; + } +} |