diff options
author | Ted Kremenek <kremenek@apple.com> | 2011-08-12 04:09:00 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2011-08-12 04:09:00 +0000 |
commit | a809447c5ce90f0efe7d6b7447d4cb6812bf3429 (patch) | |
tree | 3fea2398c90fed35e637cd287868d7f648eec51f | |
parent | 235830be84ad18c447fd477efe9b0675c203c12f (diff) |
Fix crash in CFGBuilder involving implicit destructor calls and gotos jumping after an object was declared. Fixes PR 10620.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@137426 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Analysis/CFG.cpp | 14 | ||||
-rw-r--r-- | test/SemaCXX/cfg.cpp | 23 |
2 files changed, 31 insertions, 6 deletions
diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 1edb328d01..ea126a9689 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -191,8 +191,8 @@ int LocalScope::const_iterator::distance(LocalScope::const_iterator L) { int D = 0; const_iterator F = *this; while (F.Scope != L.Scope) { - assert (F != const_iterator() - && "L iterator is not reachable from F iterator."); + if (F == const_iterator()) + return D; D += F.VarIter; F = F.Scope->Prev; } @@ -816,10 +816,12 @@ void CFGBuilder::addLocalScopeAndDtors(Stmt* S) { /// performed in place specified with iterator. void CFGBuilder::insertAutomaticObjDtors(CFGBlock* Blk, CFGBlock::iterator I, LocalScope::const_iterator B, LocalScope::const_iterator E, Stmt* S) { - BumpVectorContext& C = cfg->getBumpVectorContext(); - I = Blk->beginAutomaticObjDtorsInsert(I, B.distance(E), C); - while (B != E) - I = Blk->insertAutomaticObjDtor(I, *B++, S); + if (int Cnt = B.distance(E)) { + BumpVectorContext& C = cfg->getBumpVectorContext(); + I = Blk->beginAutomaticObjDtorsInsert(I, Cnt, C); + while (B != E) + I = Blk->insertAutomaticObjDtor(I, *B++, S); + } } /// appendAutomaticObjDtors - Append destructor CFGElements for variables with diff --git a/test/SemaCXX/cfg.cpp b/test/SemaCXX/cfg.cpp new file mode 100644 index 0000000000..93cf90ba45 --- /dev/null +++ b/test/SemaCXX/cfg.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -fsyntax-only -Wuninitialized -fsyntax-only %s + +// Test that the CFG builder handles destructors and gotos jumping between +// scope boundaries. Previously this crashed (PR 10620). +struct S_10620 { + S_10620(const S_10620 &x); + ~S_10620(); +}; +void PR10620(int x, const S_10620& s) { + if (x) { + goto done; + } + const S_10620 s2(s); +done: + ; +} +void PR10620_2(int x, const S_10620& s) { + if (x) + goto done; + const S_10620 s2(s); +done: + ; +}
\ No newline at end of file |