Page MenuHomePhabricator

MPI-Checker patch for Clang Static Analyzer
ClosedPublic

Authored by Alexander_Droste on Sep 10 2015, 7:41 AM.

Diff Detail

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

Hi Anna,

thanks for having a look once more!

tools/clang/lib/StaticAnalyzer/Checkers/Checkers.td
75 ↗(On Diff #45129)

Do you mean the 'optin' package? I could not find an 'option' package in Checkers.td.

tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.h
24 ↗(On Diff #45129)

I would prefer to put this into clang::ento::mpi, rather than having everything in a single file.

40 ↗(On Diff #45129)

Sorry about the inconsistent change. I will remove the AST related
functionality completety from this patch, as it will be part of the clang-tidy patch.

tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
43 ↗(On Diff #45129)

If sufficient, I would rename MPICheckerPathSensitive to MPICheckerPath then.
Do you mind the indirection?

tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPICheckerPathSensitive.cpp
74 ↗(On Diff #45129)

I don't think break should be called after the first error is reported. Each memory region
represents a different request, why this should be rated as multiple errors.

79 ↗(On Diff #45129)

Will do.

tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPICheckerPathSensitive.h
87 ↗(On Diff #45129)

I see, that could be confusing. Maybe renaming the variable to BReporter will do.

tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIFunctionClassifier.h
45 ↗(On Diff #45129)

These model distinct MPI function classes. I agree that it would be better to remove the unused ones, in order to keep the interface as narrow as possible.

tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPITypes.h
56 ↗(On Diff #45129)

Sure, I can do that.

tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/Utility.cpp
21 ↗(On Diff #45129)

So where shall we put sourceRange()? It is only used by the BugReporter class.
I could make it a member function of the Reporter class. Or would you prefer this
as a member function of MemRegion?

47 ↗(On Diff #45129)

These are also leftovers from the AST checks.

tools/clang/test/Analysis/MPIChecker.cpp
112 ↗(On Diff #45129)

I didn't know about expected-note, thanks!

zaks.anna added inline comments.Feb 3 2016, 2:58 PM
tools/clang/lib/StaticAnalyzer/Checkers/Checkers.td
75 ↗(On Diff #45129)

Yes, 'option'. I think it got spell checked.

tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
43 ↗(On Diff #45129)

I indirection buying us anything? I think it makes the code more difficult to follow,

tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPICheckerPathSensitive.cpp
74 ↗(On Diff #45129)

You might be right, I am not 100% sure what's more user-friendly.. Presumably the fixes are different in each case? Could you add a test case where multiple errors on the same call site are reported? (Ups can use expected-warning@+1 to report multiple warnings on the same line.)

tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/Utility.cpp
21 ↗(On Diff #45129)

I don't see why we should't add it to MemRegion. Let's submit that as a separate patch. (If someone else has a better idea they'll tell us:))

tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
43 ↗(On Diff #45129)

I think, I like the entry point class being separated from the class which does the actual checking. But the necessity for dynamicInit() maybe outweighs that. I can collapse the two.

tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPICheckerPathSensitive.cpp
74 ↗(On Diff #45129)

This is comparable to calling free on different elements, for which memory was never allocated. So each report informs about a distinct missing nonblocking call. I'll give expected-warning@+1 a try.

Alexander_Droste marked 36 inline comments as done.Feb 25 2016, 1:45 AM
Alexander_Droste added inline comments.
tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPICheckerPathSensitive.cpp
79 ↗(On Diff #45129)

Changed this to the same ErrorNode/State pattern like in checkMissingWaits.

tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIFunctionClassifier.h
45 ↗(On Diff #45129)

I'd like to keep some of the classes/identifiers that are not used in this patch
but will be in the clang-tidy patch, as discussed with Alexander Kornienko.

tools/clang/test/Analysis/MPIChecker.cpp
112 ↗(On Diff #45129)

I changed the plain comments to // expected-note{{..}} but all tests using an expected note fail by claiming:

error: 'note' diagnostics expected but not seen:
File .../MPIChecker.cpp Line 112: Request is previously used by nonblocking call here.

Though, running the MPI-Checker on this function, the HTML report contains this exact note
at the expected position. The output is produced at the end of MPIBugReporter::RequestNodeVisitor::VisitNode.

Is there something missing, in order to make this an expected note?

Alexander_Droste marked 2 inline comments as done.
  • fixed checkUnmatchedWaits (added ErrorNode)
  • non fatal error node for double nonblocking
  • renamed BugReporter variable to BReporter
  • description why custom RequestMap is used
  • collapse pathsensitivechecker with mpichecker
  • mpi-checker move to optin package
  • moved sourceRange() memregion.cpp/h
  • remove Utility.cpp/h
  • put everything into clang::ento
  • remove '––––' from comments
  • test case checking for multiple missing nonblocking calls in the same line (// expected-warning-re 1+{{Request {{.*}} has..)
  • removed some of the mpi classifications/identifiers
lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
39

The MemRegion sourceRange() patch is not under review yet. I will submit the patch for after http://reviews.llvm.org/D16044 got accepted.

  • removed commented out line
  • removed dashes '–––' from comment in MPIChecker.cpp testfile
  • (diff is created with clang as pwd)
lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
47

This should actually be reportDoubleNonblocking(..., ErrorNode); instead of ExplNode, right?

  • use MPI mock header in integration test file

Some comments inline. I still have to do an overall pass over this checker, but it looks much better than the first version!

lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
48

Correct, it should be ErrorNode. Moreover, if you do not modify the State and use the state from the predecessor node, which is the case here, you do not need to pass a State to it. You do not need to pass the tag either in his case - a page generated for your checker will be used. By default the CheckerContext will use the state of the predecessor node and that default tag. (If you want to pass your tag, it's fine.)

You do need to pass the state if you modify the state as in the next example.

85

Here you do need to pass State.

136

I do not think I've seen this code before. If you add new functionality, please submit it in a new commit. Otherwise, there is a high chance it will go unnoticed.

Are there examples of the new warnings it caught?

checkEndAnalysis is rarely used by checkers, so you might not need it here. Specifically, you should be notified by the checkDeadSymbols before a symbol dies even if it dies because it's the end of path.

Alexander_Droste marked 3 inline comments as done.Mar 13 2016, 3:40 AM

I still have to do an overall pass over this checker, but it looks much better than the first version!

:D

lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
48

Ah I see, this is covered by the default parameters.

136

Yes, I added this at some point after the initial patch, after I realized that the following test case fails:

MPI_Request sendReq1;
void missingWait2() { // Check missing wait for global variable.
  int rank = 0;
  double buf = 0;
  MPI_Comm_rank(MPI_COMM_WORLD, &rank);
  MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM, 0, MPI_COMM_WORLD, &sendReq1);
} // expected-warning{{Request 'sendReq1' has no matching wait.}}

if the checker solely relies on checkDeadSymbols. I just rechecked this behavior by commenting out

BReporter->reportMissingWait(Req.second, Req.first, *NodeIt);

in checkMissingWaitsGlobals and the test still fails then. Are global variables really covered by checkDeadSymbols?

Alexander_Droste marked an inline comment as done.
  • omit superfluous arguments passed to generateNonFatalErrorNode
test/Analysis/MPIChecker.cpp
98

All the expected-notes still fail, even though the diagnostics are presented in a report.

zaks.anna added inline comments.Mar 13 2016, 10:13 AM
lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
137

The analyzer does not do a good job tracking global variables. You might get false positives, specifically, where the variable is released in another translation unit or by calling function that the analyzer does not inline.

lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
137

So shall we remove or keep the function?

zaks.anna added inline comments.Mar 21 2016, 8:48 AM
lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
137

I think you will get false positives of the nature I describe above if you keep it. If so, you should remove it. The user experience is much better if you avoid false positives.

  • remove checkMissingWaitsGlobals to prevent potential false positives
Alexander_Droste marked 6 inline comments as done.Mar 21 2016, 9:43 AM
Alexander_Droste added inline comments.
lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
40

sourceRange patch -> http://reviews.llvm.org/D18309

lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
137

I removed the function.

zaks.anna added inline comments.Mar 28 2016, 8:09 PM
test/Analysis/MPIChecker.cpp
99

Do you see the notes in the report? I think you should pass "-analyzer-output=text" to see the notes.

zaks.anna added inline comments.Mar 28 2016, 11:09 PM
lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
96

Would it be possible to identify the "interesting node" by just looking at how the state you track changes. This function will be called when we walk the path upward from the error node. For example, you can notice that in the previous state, the Request did not exist and in this state it is Nonblocking. That would allow you to conclude that between those 2 states a function was called. (This is the trick we use in the other checkers (ex: malloc); it simplifies implementation and makes it more robust - we do not need to pattern match as much.)

lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
87

Can you add a test cases for this report when there are multiple ReqRegions? Looks like all of the test cases with MPI_Waitall succeed. (I test a case where one of the regions has a match in Waitall and one does not as well as when several/all do not have a match.)

test/Analysis/MPIChecker.cpp
114

Are we allowed to call reduce -> wait -> reduce with the same req? If so, let's test for that.

Also, can calls to reduce and wait occur in different functions? If so, we need to test cases where they occur in different functions that are all in the same translation unit - all of the implementations are visible to the analyzer. And also test the cases where we pass the request to a function, whose body is not visible to the analyzer, which is the case when the function is defined in another translation unit.

Alexander_Droste marked 3 inline comments as done.Mar 30 2016, 3:02 AM
Alexander_Droste added inline comments.
lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
96

I think this should work but would slightly change the way diagnostics are presented in a specific case. If more than 2 nonblocking calls are using a request in sequence, the expected note (Request is previously used by nonblocking call here.) would not point to the previous but to the first nonblocking call of that sequence. What do you think; should the VisitNode function be changed regardless or should it stay as it is because of this specific case?

lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
87

Sure, I'll add those tests. The case where none of the requests is matched should be covered by missingNonBlockingMultiple.

test/Analysis/MPIChecker.cpp
99

If I pass -analyzer-output=text I see the notes in the report. But adding that flag also produces a lot of 'undesired' output like: Loop condition is true. Entering loop body.

114

Are we allowed to call reduce -> wait -> reduce with the same req? If so, let's test for that.

Yes, that's allowed. I'll add a test.

Also, can calls to reduce and wait occur in different functions?

This is also possible.

And also test the cases where we pass the request to a function, whose body is not visible to the analyzer, which is the case when the function is defined in another translation unit.

I would then simply create a new pair of .cpp and .h files in the test folder where I define those functions so that the MPI-Checker tests can use them.

Alexander_Droste updated this object.
  • added test that uses wrapper functions around MPI functions
  • added test to check behavior in case MPI functions are used in other translation units
  • added more MPI_Waitall tests -> missingNonBlockingWaitall*
  • check memory regions for nullptr in checkDoubleNonblocking and checkUnmatchedWaits before they get passed to dyn_cast<ElementRegion>

Alexander,

This patch is in a pretty good shape. I am fine with committing it and iterating with smaller updates in tree if it is more convenient for you.

One task that I would like to very strongly encourage is running this on a lot of code. You will find a lot of issues this way that are hard to discover during code review. Both false positives and crashes.

Thanks!
Anna.

lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
97

The advantage of using the state is that it will be much more robust to any further changes to the compiler/checker because you will not be pattern matching the AST but instead will be checking the state, which the core reasoning is based on. One example that comes to mind is indirect calls. You will reduce the amount of code here as well, simplifying maintainability. This is the pattern we use in other checkers as well, so there is a remote chance we could introduce a new simplified API that will do the walk for the checker writers.

With respect to your example. Does it come up in practice? Wouldn't you warn on the second nonblocking request anyway? Could you add such an example to the tests? (Would be good in any case. If you leave the code as is, you can point to that example as the motivation.)

lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
88

This is done, right?

test/Analysis/MPIChecker.cpp
100

This are explaining the path on which the problem occurs; the users will see them as well. There should not be a lot of those, you do not have a lot of conditions. Would it be reasonable to change the tests to incorporate those. Other alternative is to have another tests file that tests the notes in that mode.

What do you think?

115

I would then simply create a new pair of .cpp and .h files in the test folder
where I define those functions so that the MPI-Checker tests can use them.

You do not have to do that. You could just declare the functions and not define them. It will be equivalent to having the definitions in the other TUs.

alexfh removed a subscriber: alexfh.Apr 12 2016, 12:10 PM

Hi Anna,

I am fine with committing it and iterating with smaller updates in tree if it is more convenient for you.

This sounds good! The last thing I'll change before are the improvements you pointed out.

One task that I would like to very strongly encourage is running this on a lot of code.

Good idea. I'll do that.

Thanks a lot for all the time and effort you invested into the review!

lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp
88

Yep.

test/Analysis/MPIChecker.cpp
100

I'm fine with adding the notes to this test file.

115

Like you suggested, I'll simply declare the functions without definition.

test/Analysis/MPIChecker.cpp
100

I had a look once more how much output this actually produces. If -analyzer-output=text is passed, 42 notes are missing. I'll add another test file which will test for these notes.

lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp
97

I'll change this to the pattern you suggested.

With respect to your example. Does it come up in practice?

It's for sure a little contrived.

Wouldn't you warn on the second nonblocking request anyway?

Yes.

Could you add such an example to the tests?

Sure.

  • added test file to test for note diagnostics
  • changed BugReportVisitor to detect request usage purely based on state and existence of a request
  • added test that showcases a triple nonblocking usage of a request
Alexander_Droste marked 20 inline comments as done.Apr 16 2016, 4:12 AM
zaks.anna accepted this revision.Apr 16 2016, 11:37 AM
zaks.anna edited edge metadata.

Awesome!

Thank you for investing SO MUCH time into improving the checker and addressing the review comments.
Do you have commit access?

Nit: Please, use lower case letters for test names to be consistent with the rest.

This revision is now accepted and ready to land.Apr 16 2016, 11:37 AM
Alexander_Droste edited edge metadata.
  • lower case letters for test filenames

Yeah; I'm excited to see that this code will now be part of LLVM. Thanks to everybody reviewing the patch!
I don't have commit access. Can you commit the bundle of related patches for me?

Anna, will you commit this, or do you want me to commit the patches?

This revision was automatically updated to reflect the committed changes.

This doesn't compile under gcc so it broke the bots. The fix is to move the specialization of clang::ento::ProgramStateTrait for RequestMapImpl out of the global namespace and into clang::ento. I will apply and recommit.

Fixed the compilation issues with gcc in r271977 r271981, but it is still failing with Address Sanitizer diagnostics:

18751==ERROR: AddressSanitizer: stack-use-after-return on address 0x7f0c695ebc70 at pc 0x00000867b44c bp 0x7ffe3b01d6f0 sp 0x7ffe3b01d6e8

READ of size 8 at 0x7f0c695ebc70 thread T0

#0 0x867b44b in getSourceManager /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h:448:46
#1 0x867b44b in clang::ento::BugReporter::emitReport(std::__1::unique_ptr<clang::ento::BugReport, std::__1::default_delete<clang::ento::BugReport> >) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Core/BugReporter.cpp:3240
#2 0x8636355 in clang::ento::mpi::MPIBugReporter::reportUnmatchedWait(clang::ento::CallEvent const&, clang::ento::MemRegion const*, clang::ento::ExplodedNode const*) const /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIBugReporter.cpp:82:3
#3 0x843e1ee in clang::ento::mpi::MPIChecker::checkUnmatchedWaits(clang::ento::CallEvent const&, clang::ento::CheckerContext&) const /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.cpp:88:7
#4 0x8447dc8 in checkPreCall /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Checkers/MPI-Checker/MPIChecker.h:36:5
#5 0x8447dc8 in void clang::ento::check::PreCall::_checkCall<clang::ento::mpi::MPIChecker>(void*, clang::ento::CallEvent const&, clang::ento::CheckerContext&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Checker.h:168
#6 0x86db2f2 in operator() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h:59:12
#7 0x86db2f2 in runChecker /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp:269
#8 0x86db2f2 in expandGraphWithCheckers<(anonymous namespace)::CheckCallContext> /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp:123
#9 0x86db2f2 in clang::ento::CheckerManager::runCheckersForCallEvent(bool, clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNodeSet const&, clang::ento::CallEvent const&, clang::ento::ExprEngine&, bool) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Core/CheckerManager.cpp:285
#10 0x8782a84 in runCheckersForPreCall /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/include/clang/StaticAnalyzer/Core/CheckerManager.h:252:5
#11 0x8782a84 in clang::ento::ExprEngine::evalCall(clang::ento::ExplodedNodeSet&, clang::ento::ExplodedNode*, clang::ento::CallEvent const&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp:509
#12 0x878205b in clang::ento::ExprEngine::VisitCallExpr(clang::CallExpr const*, clang::ento::ExplodedNode*, clang::ento::ExplodedNodeSet&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp:487:5
#13 0x872a0d8 in clang::ento::ExprEngine::Visit(clang::Stmt const*, clang::ento::ExplodedNode*, clang::ento::ExplodedNodeSet&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:1104:7
#14 0x87210bf in clang::ento::ExprEngine::ProcessStmt(clang::CFGStmt, clang::ento::ExplodedNode*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:448:5
#15 0x87207ae in clang::ento::ExprEngine::processCFGElement(clang::CFGElement, clang::ento::ExplodedNode*, unsigned int, clang::ento::NodeBuilderContext*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Core/ExprEngine.cpp:297:7
#16 0x86fc7a6 in clang::ento::CoreEngine::HandlePostStmt(clang::CFGBlock const*, unsigned int, clang::ento::ExplodedNode*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:515:5
#17 0x86fafed in clang::ento::CoreEngine::dispatchWorkItem(clang::ento::ExplodedNode*, clang::ProgramPoint, clang::ento::WorkListUnit const&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:274:7
#18 0x86f9891 in clang::ento::CoreEngine::ExecuteWorkList(clang::LocationContext const*, unsigned int, llvm::IntrusiveRefCntPtr<clang::ento::ProgramState const>) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Core/CoreEngine.cpp:231:5
#19 0x67f1ab5 in ExecuteWorkList /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/include/clang/StaticAnalyzer/Core/PathSensitive/ExprEngine.h:109:12
#20 0x67f1ab5 in (anonymous namespace)::AnalysisConsumer::ActionExprEngine(clang::Decl*, bool, clang::ento::ExprEngine::InliningModes, llvm::DenseSet<clang::Decl const*, llvm::DenseMapInfo<clang::Decl const*> >*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:664
#21 0x67f0ae2 in RunPathSensitiveChecks /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:694:5
#22 0x67f0ae2 in (anonymous namespace)::AnalysisConsumer::HandleCode(clang::Decl*, unsigned int, clang::ento::ExprEngine::InliningModes, llvm::DenseSet<clang::Decl const*, llvm::DenseMapInfo<clang::Decl const*> >*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:632
#23 0x67dc135 in HandleDeclsCallGraph /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:495:5
#24 0x67dc135 in (anonymous namespace)::AnalysisConsumer::HandleTranslationUnit(clang::ASTContext&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:547
#25 0x687dae4 in clang::ParseAST(clang::Sema&, bool, bool) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Parse/ParseAST.cpp:167:3
#26 0x51c090b in clang::FrontendAction::Execute() /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Frontend/FrontendAction.cpp:457:8
#27 0x510f614 in clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/Frontend/CompilerInstance.cpp:876:7
#28 0x537fa92 in clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:241:18
#29 0x8fc2f2 in cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/driver/cc1_main.cpp:116:13
#30 0x8f6a88 in ExecuteCC1Tool /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/driver/driver.cpp:301:12
#31 0x8f6a88 in main /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/tools/driver/driver.cpp:381
#32 0x7f0c6c208f44 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x21f44)
#33 0x816952 in _start (/mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm_build_asan/bin/clang-3.9+0x816952)

Address 0x7f0c695ebc70 is located in stack of thread T0 at offset 1136 in frame

  #0 0x67f130f in (anonymous namespace)::AnalysisConsumer::ActionExprEngine(clang::Decl*, bool, clang::ento::ExprEngine::InliningModes, llvm::DenseSet<clang::Decl const*, llvm::DenseMapInfo<clang::Decl const*> >*) /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/lib/StaticAnalyzer/Frontend/AnalysisConsumer.cpp:644

This frame has 5 object(s):
  [32, 184) 'P.i'
  [256, 260) 'FD.i'
  [272, 296) 'ref.tmp.i'
  [336, 344) 'agg.tmp.i'
  [368, 1248) 'Eng' <== Memory access at offset 1136 is inside this variable

HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext

(longjmp and C++ exceptions *are* supported)

SUMMARY: AddressSanitizer: stack-use-after-return /mnt/b/sanitizer-buildbot3/sanitizer-x86_64-linux-fast/build/llvm/tools/clang/include/clang/StaticAnalyzer/Core/BugReporter/BugReporter.h:448:46 in getSourceManager
Shadow bytes around the buggy address:

0x0fe20d2b5730: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x0fe20d2b5740: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x0fe20d2b5750: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x0fe20d2b5760: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x0fe20d2b5770: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5

>0x0fe20d2b5780: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5[f5]f5

0x0fe20d2b5790: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x0fe20d2b57a0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x0fe20d2b57b0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x0fe20d2b57c0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
0x0fe20d2b57d0: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5

Shadow byte legend (one shadow byte represents 8 application bytes):

Addressable:           00
Partially addressable: 01 02 03 04 05 06 07 
Heap left redzone:       fa
Heap right redzone:      fb
Freed heap region:       fd
Stack left redzone:      f1
Stack mid redzone:       f2
Stack right redzone:     f3
Stack partial redzone:   f4
Stack after return:      f5
Stack use after scope:   f8
Global redzone:          f9
Global init order:       f6
Poisoned by user:        f7
Container overflow:      fc
Array cookie:            ac
Intra object redzone:    bb
ASan internal:           fe
Left alloca redzone:     ca
Right alloca redzone:    cb

18751==ABORTING


Testing: 0
FAIL: Clang :: Analysis/mpicheckernotes.cpp (317 of 9433)