From 2ee73b86c0ad30efcfa0be7668b04b848076e710 Mon Sep 17 00:00:00 2001 From: Ted Kremenek Date: Mon, 11 May 2009 22:19:32 +0000 Subject: [PATCH] EdgeBuilder: DeclStmts and BinaryOperators are not the enclosing location context when they are used as initialization code for loops. llvm-svn: 71480 --- clang/lib/Analysis/BugReporter.cpp | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/clang/lib/Analysis/BugReporter.cpp b/clang/lib/Analysis/BugReporter.cpp index 5407cea4e2ca..23f334239987 100644 --- a/clang/lib/Analysis/BugReporter.cpp +++ b/clang/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); }