Fix crash in CFGBuilder involving implicit destructor calls and gotos jumping after an object was declared. Fixes PR 10620.

llvm-svn: 137426
This commit is contained in:
Ted Kremenek
2011-08-12 04:09:00 +00:00
parent 4826b7f13a
commit 06b8cd7324
2 changed files with 31 additions and 6 deletions

View File

@@ -191,8 +191,8 @@ int LocalScope::const_iterator::distance(LocalScope::const_iterator L) {
int D = 0; int D = 0;
const_iterator F = *this; const_iterator F = *this;
while (F.Scope != L.Scope) { while (F.Scope != L.Scope) {
assert (F != const_iterator() if (F == const_iterator())
&& "L iterator is not reachable from F iterator."); return D;
D += F.VarIter; D += F.VarIter;
F = F.Scope->Prev; F = F.Scope->Prev;
} }
@@ -816,10 +816,12 @@ void CFGBuilder::addLocalScopeAndDtors(Stmt* S) {
/// performed in place specified with iterator. /// performed in place specified with iterator.
void CFGBuilder::insertAutomaticObjDtors(CFGBlock* Blk, CFGBlock::iterator I, void CFGBuilder::insertAutomaticObjDtors(CFGBlock* Blk, CFGBlock::iterator I,
LocalScope::const_iterator B, LocalScope::const_iterator E, Stmt* S) { LocalScope::const_iterator B, LocalScope::const_iterator E, Stmt* S) {
BumpVectorContext& C = cfg->getBumpVectorContext(); if (int Cnt = B.distance(E)) {
I = Blk->beginAutomaticObjDtorsInsert(I, B.distance(E), C); BumpVectorContext& C = cfg->getBumpVectorContext();
while (B != E) I = Blk->beginAutomaticObjDtorsInsert(I, Cnt, C);
I = Blk->insertAutomaticObjDtor(I, *B++, S); while (B != E)
I = Blk->insertAutomaticObjDtor(I, *B++, S);
}
} }
/// appendAutomaticObjDtors - Append destructor CFGElements for variables with /// appendAutomaticObjDtors - Append destructor CFGElements for variables with

View File

@@ -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:
;
}