Hi all,
I’m working on a checker rule which is functioning well, but the bug reports it emits are quite problematic. Instead of reporting the source location that is interesting to the developer, it reports a very different location.
Through my testing I’ve identified that my problem comes down to my need to emit the report late. I catch the potential trouble early, but I need to keep exploring to ensure that the problem exists before I can emit the bug report. As such, I don’t generate the error node until later in the analysis. I hold onto the relevant SourceRange object at the time of detection so that I can reference it later in the report, but it doesn’t seem to be doing much of anything.
I’m using code like the following to emit my report:
clang::ento::ExplodedNode *error = C.generateNonFatalErrorNode();
if (error == nullptr) {
return;
}
auto report = llvm::make_uniqueclang::ento::BugReport(*bugType, text, error);
report->addRange(sourceRange);
C.emitReport(std::move(report));
I’ve confirmed that “sourceRange” is, in fact, the desired range (and is valid), via its dump() function. Yet in my test case, while the sourceRange states “file:6:4 - file:6:13”, I end up getting a report on the next line (which is not interesting to the developer). I’ve noticed that if I emit my report immediately, rather than holding the source range for later, the emitted report is correct.
Is there anything special I need to do here? Or what am I doing wrong when emitting my reports such that clang is refusing to reference my supplied source range?
For reference, I tried to boil my checker down to a minimalist case that reproduces my trouble (attached). I mark the source range during the call to checkPostCall and then later emit all captured ranges during checkEndFunction. (Note that I’m not actually using check::EndFunction in my checker; it was just the easiest way to reproduce this.) The test file I’m running this checker against follows, from which I expect two reports, both on line 6, but I end up getting a single report marking the ‘}’ on line 7 instead:
int foo();
void bar(int);
void baz()
{
bar(foo());
}
Thanks for any advice,
– Matthew P. Del Buono
checkerReproduction.cpp (2.07 KB)