[PATCH] Append CXXDefaultInitExpr's wrapped expression to the CFG when visiting a constructor initializer
Enrico Pertoso
epertoso at google.com
Wed Dec 11 08:32:23 PST 2013
================
Comment at: lib/StaticAnalyzer/Core/BugReporter.cpp:282-294
@@ -267,6 +281,15 @@
} else if (End && isa<CXXDefaultInitExpr>(End)) {
- PathPieces::iterator Next = llvm::next(I);
- if (Next != E) {
- if (PathDiagnosticControlFlowPiece *NextCF =
- dyn_cast<PathDiagnosticControlFlowPiece>(*Next)) {
- NextCF->setStartLocation(CF->getStartLocation());
+ const Expr *InitExpr = cast<CXXDefaultInitExpr>(End)->getExpr();
+ if (Start && containsStmt(InitExpr, Start)) {
+ if (I != Pieces.begin()) {
+ PathPieces::iterator Prev = llvm::prior(I);
+ if (PathDiagnosticControlFlowPiece *PrevCF =
+ dyn_cast<PathDiagnosticControlFlowPiece>(*Prev)) {
+ CF->setStartLocation(PrevCF->getStartLocation());
+ Start = CF->getStartLocation().asStmt();
+ Pieces.erase(Prev);
+ continue;
+ }
+ }
+ } else {
+ PathPieces::iterator Next = llvm::next(I);
----------------
Jordan Rose wrote:
> This definitely needs testing. The whole point of this section is to make Xcode arrows prettier, so without a test case that actually includes a plist it's kind of useless.
>
> If you have Xcode, you can test the new arrows by overriding the analyzer binary with the not-so-secret setting CLANG_ANALYZER_EXEC. If not, don't worry about the arrows for now; I'll get to them soon.
`test/Analysis/edges-new.mm` is actually a plist based test and without changes to this section it was failing (a `CXXDefaultInitExpr` may now include the field initializer, so it may spawn more than a `PathDiagnosticControlFlowPiece`).
I modified it a little bit (inserting a conditional operator in `edges-new.mm` at line `580`) to make sure that there's no arrow pointing to (or starting from) the actual init expression.
================
Comment at: lib/StaticAnalyzer/Core/BugReporter.cpp:251-261
@@ +250,13 @@
+/// the second statement.
+static bool containsStmt(const Stmt *Ex, const Stmt *S) {
+ if (Ex == S)
+ return true;
+
+ for (Stmt::const_child_iterator I = Ex->child_begin(), E = Ex->child_end();
+ I != E; ++I) {
+ if (containsStmt(*I, S))
+ return true;
+ }
+ return false;
+}
+
----------------
Jordan Rose wrote:
> Usually we do this using ParentMap so that it's a linear search. We'd have to start adding the children of the CXXDefaultInitExpr to the ParentMap, though.
We don't actually need to know a statement's parent, I used a `llvm::DenseSet` instead. Unlike the ParentMap, it can be cleared.
http://llvm-reviews.chandlerc.com/D2370
More information about the cfe-commits
mailing list