forked from OSchip/llvm-project
[analyzer; new edges] Include a top-level function entry edge while optimizing.
Although we don't want to show a function entry edge for a top-level path, having it makes optimizing edges a little more uniform. This does not affect any edges now, but will affect context edge generation (next commit). llvm-svn: 183158
This commit is contained in:
parent
5250b873bb
commit
c892bb04ca
|
@ -1820,6 +1820,14 @@ GenerateAlternateExtensivePathDiagnostic(PathDiagnostic& PD,
|
|||
}
|
||||
}
|
||||
|
||||
// Add an edge to the start of the function.
|
||||
// We'll prune it out later, but it helps make diagnostics more uniform.
|
||||
const StackFrameContext *CalleeLC = PDB.LC->getCurrentStackFrame();
|
||||
const Decl *D = CalleeLC->getDecl();
|
||||
addEdgeToPath(PD.getActivePath(), PrevLoc,
|
||||
PathDiagnosticLocation::createBegin(D, SM),
|
||||
CalleeLC);
|
||||
|
||||
return report->isValid();
|
||||
}
|
||||
|
||||
|
@ -2057,12 +2065,8 @@ static bool optimizeEdges(PathPieces &path, SourceManager &SM,
|
|||
const LocationContext *LC = LCM[&path];
|
||||
assert(LC);
|
||||
ParentMap &PM = LC->getParentMap();
|
||||
bool isFirst = true;
|
||||
|
||||
for (PathPieces::iterator I = path.begin(), E = path.end(); I != E; ) {
|
||||
bool wasFirst = isFirst;
|
||||
isFirst = false;
|
||||
|
||||
// Optimize subpaths.
|
||||
if (PathDiagnosticCallPiece *CallI = dyn_cast<PathDiagnosticCallPiece>(*I)){
|
||||
// Record the fact that a call has been optimized so we only do the
|
||||
|
@ -2089,25 +2093,6 @@ static bool optimizeEdges(PathPieces &path, SourceManager &SM,
|
|||
const Stmt *level1 = getStmtParent(s1Start, PM);
|
||||
const Stmt *level2 = getStmtParent(s1End, PM);
|
||||
|
||||
if (wasFirst) {
|
||||
// If the first edge (in isolation) is just a transition from
|
||||
// an expression to a parent expression then eliminate that edge.
|
||||
if (level1 && level2 && level2 == PM.getParent(level1)) {
|
||||
path.erase(I);
|
||||
// Since we are erasing the current edge at the start of the
|
||||
// path, just return now so we start analyzing the start of the path
|
||||
// again.
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the first edge (in isolation) is a transition from the
|
||||
// initialization or increment in a for loop then remove it.
|
||||
if (level1 && isIncrementOrInitInForLoop(s1Start, level1)) {
|
||||
path.erase(I);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
PathPieces::iterator NextI = I; ++NextI;
|
||||
if (NextI == E)
|
||||
break;
|
||||
|
@ -2427,6 +2412,23 @@ static void simplifySimpleBranches(PathPieces &pieces) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Drop the very first edge in a path, which should be a function entry edge.
|
||||
static void dropFunctionEntryEdge(PathPieces &Path,
|
||||
LocationContextMap &LCM,
|
||||
SourceManager &SM) {
|
||||
#ifndef NDEBUG
|
||||
const Decl *D = LCM[&Path]->getDecl();
|
||||
PathDiagnosticLocation EntryLoc =
|
||||
PathDiagnosticLocation::createBegin(D, SM);
|
||||
const PathDiagnosticControlFlowPiece *FirstEdge =
|
||||
cast<PathDiagnosticControlFlowPiece>(Path.front());
|
||||
assert(FirstEdge->getStartLocation() == EntryLoc && "not an entry edge");
|
||||
#endif
|
||||
|
||||
Path.pop_front();
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Methods for BugType and subclasses.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -3126,6 +3128,10 @@ bool GRBugReporter::generatePathDiagnostic(PathDiagnostic& PD,
|
|||
// Hoist edges originating from branch conditions to branches
|
||||
// for simple branches.
|
||||
simplifySimpleBranches(PD.getMutablePieces());
|
||||
|
||||
// Drop the very first function-entry edge. It's not really necessary
|
||||
// for top-level functions.
|
||||
dropFunctionEntryEdge(PD.getMutablePieces(), LCM, SM);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue