From: Ted Kremenek Date: Mon, 11 May 2009 22:19:32 +0000 (+0000) Subject: EdgeBuilder: DeclStmts and BinaryOperators are not the enclosing location context... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=e88a170da9219ef6a62d2182560c4de2ebffbd59;p=clang EdgeBuilder: DeclStmts and BinaryOperators are not the enclosing location context when they are used as initialization code for loops. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@71480 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Analysis/BugReporter.cpp b/lib/Analysis/BugReporter.cpp index 5407cea4e2..23f3342399 100644 --- a/lib/Analysis/BugReporter.cpp +++ b/lib/Analysis/BugReporter.cpp @@ -212,7 +212,7 @@ PathDiagnosticBuilder::getEnclosingStmtLocation(const Stmt *S) { assert(S && "Null Stmt* passed to getEnclosingStmtLocation"); ParentMap &P = getParentMap(); SourceManager &SMgr = getSourceManager(); - + while (isa(S) && P.isConsumedExpr(cast(S))) { const Stmt *Parent = P.getParentIgnoreParens(S); @@ -269,6 +269,31 @@ PathDiagnosticBuilder::getEnclosingStmtLocation(const Stmt *S) { } assert(S && "Cannot have null Stmt for PathDiagnosticLocation"); + + // Special case: DeclStmts can appear in for statement declarations, in which + // case the ForStmt is the context. + if (isa(S)) { + if (const Stmt *Parent = P.getParent(S)) { + switch (Parent->getStmtClass()) { + case Stmt::ForStmtClass: + case Stmt::ObjCForCollectionStmtClass: + return PathDiagnosticLocation(Parent, SMgr); + default: + break; + } + } + } + else if (isa(S)) { + // Special case: the binary operator represents the initialization + // code in a for statement (this can happen when the variable being + // initialized is an old variable. + if (const ForStmt *FS = + dyn_cast_or_null(P.getParentIgnoreParens(S))) { + if (FS->getInit() == S) + return PathDiagnosticLocation(FS, SMgr); + } + } + return PathDiagnosticLocation(S, SMgr); }