From: Ted Kremenek Date: Thu, 22 Mar 2012 05:57:43 +0000 (+0000) Subject: Fix broken CFG when an initializer is a statement expression that starts with a while... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=550f2234fc9218914c325041067052342dfce553;p=clang Fix broken CFG when an initializer is a statement expression that starts with a while loop (PR 12325). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@153242 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/CFG.cpp b/lib/Analysis/CFG.cpp index 24ca958827..d0ccef6890 100644 --- a/lib/Analysis/CFG.cpp +++ b/lib/Analysis/CFG.cpp @@ -1464,14 +1464,24 @@ CFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt *DS) { autoCreateBlock(); appendStmt(Block, DS); + + // Keep track of the last non-null block, as 'Block' can be nulled out + // if the initializer expression is something like a 'while' in a + // statement-expression. + CFGBlock *LastBlock = Block; if (Init) { - if (HasTemporaries) + if (HasTemporaries) { // For expression with temporaries go directly to subexpression to omit // generating destructors for the second time. - Visit(cast(Init)->getSubExpr()); - else - Visit(Init); + ExprWithCleanups *EC = cast(Init); + if (CFGBlock *newBlock = Visit(EC->getSubExpr())) + LastBlock = newBlock; + } + else { + if (CFGBlock *newBlock = Visit(Init)) + LastBlock = newBlock; + } } // If the type of VD is a VLA, then we must process its size expressions. @@ -1483,7 +1493,7 @@ CFGBlock *CFGBuilder::VisitDeclSubExpr(DeclStmt *DS) { if (ScopePos && VD == *ScopePos) ++ScopePos; - return Block; + return Block ? Block : LastBlock; } CFGBlock *CFGBuilder::VisitIfStmt(IfStmt *I) { diff --git a/test/SemaCXX/uninitialized.cpp b/test/SemaCXX/uninitialized.cpp index 9550682918..15c06eb421 100644 --- a/test/SemaCXX/uninitialized.cpp +++ b/test/SemaCXX/uninitialized.cpp @@ -147,3 +147,18 @@ namespace rdar10398199 { (void)y; }; } + +// PR 12325 - this was a false uninitialized value warning due to +// a broken CFG. +int pr12325(int params) { + int x = ({ + while (false) + ; + int _v = params; + if (false) + ; + _v; // no-warning + }); + return x; +} +