This is an archive of the discontinued LLVM Phabricator instance.

[Analyzer] Improve report of file read at end-of-file condition.
ClosedPublic

Authored by balazske on Jun 25 2021, 8:49 AM.

Details

Summary

The checker warns if a stream is read that is already in EOF state.
The commit adds indication of locations where the EOF flag is set
on the stream and where it is discovered by the program.

Diff Detail

Event Timeline

balazske created this revision.Jun 25 2021, 8:49 AM
balazske requested review of this revision.Jun 25 2021, 8:49 AM
Herald added a project: Restricted Project. · View Herald TranscriptJun 25 2021, 8:49 AM
Herald added a subscriber: cfe-commits. · View Herald Transcript
balazske updated this revision to Diff 354791.Jun 27 2021, 11:53 PM

Add checker name to commit message.

NoQ added a comment.Jun 28 2021, 11:21 AM

Thanks! Why isn't this a NoteTag?

I could not find a way to pass the needed information from the BugReport to the NoteTag. The "sequence number" (in EofSeqMap) is only known when the bug is detected, this should be passed to the NoteTag somehow. The value is used to make the new note appear only at the last place where EOF is set.

Is it better to save the actual ExplodedNode in the note tag? Then the error node of the BugReport can be used to search the bug path and check if the saved node is encountered. In this way a NoteTag could be used and the "sequence numbers" would be unnecessary.

NoQ added a comment.Jun 29 2021, 1:50 PM

I could not find a way to pass the needed information from the BugReport to the NoteTag. The "sequence number" (in EofSeqMap) is only known when the bug is detected, this should be passed to the NoteTag somehow.

You can capture it.

That's the whole point of note tags, to have access to all the information from both the bug report and the moment of time the event has happened.

+1 for note tags.

clang/test/Analysis/stream-note.c
134

Perhaps we could have some more explanatory test case names. I mean how _3 is different than _2? What is the case each of them exactly tests?

141

Strictly speaking it is not necessarily and end-of-file status, ferror indicates if there was an error.

balazske updated this revision to Diff 355594.Jun 30 2021, 9:30 AM

Using NoteTag.
Removed the EOF sequence number.
Renamed test functions.

balazske marked an inline comment as done.Jun 30 2021, 9:31 AM

Updated to use NoteTag.
Note "End-of-file status is discovered here" is removed.

clang/test/Analysis/stream-note.c
141

Exacly the ferror(F) is false here. If it is false we may have successful read or EOF after read. So the message about "Assuming that stream reaches end-of-file here" is really an assumption here (pick one from the two possible results). And if EOF happens and ferror is false the feof must be true, this is revealed when we know that ferror is false.

NoQ added a comment.Jul 1 2021, 1:48 AM

Let's simplify this even further!

clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
430–432

I guess it's a matter of preference but I really don't understand the need to define a structure when a lambda is sufficient. Lambda is the intended syntax sugar for exactly what you have written.

436–437

You can compare BugType objects directly (by address).

440–446

This code says "If there exists a state below in the path where the stream is not at EOF, drop the note". The report will not be emitted at all if the stream is not at EOF at the end, right? Are you trying to account for the situation when the stream gets reset into a non-EOF state and therefore you don't need to emit the note above that point?

In such cases the intended solution is to add another note tag to mark the stream uninteresting once it gets reset, because all the history before that point is irrelevant to our report entirely (whatever the previous position was, its get completely overwritten by the reset).

The API for marking objects uninteresting is not yet there but it's suggested in D104300. I believe you should rebase your patch on top of it and take advantage of it as it lands.

balazske added inline comments.Jul 1 2021, 8:52 AM
clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
430–432

The reason is that the NoteTag is added at more than one place. And I do not want a function that returns a lambda.

440–446

It was unknown to me if the visit of NoteTag's happens from the bug path end to begin or in different way. If it is from end to begin it may be enough to remove the interestingness in the current NoteTag function when a message is produced, it should find exactly the last place where that EOF flag is set to true. And NotePosition is not needed.

440–446

I tried it out, seems to work. But to continue D104300 should be finished or the "reset of interestingness" must be split to a separate change (or into this patch), is this possible?

martong added inline comments.Jul 2 2021, 5:43 AM
clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
440–446

I tried it out, seems to work. But to continue D104300 should be finished or the "reset of interestingness" must be split to a separate change (or into this patch), is this possible?

Yes, I think it would be the logical way forward if we want a smooth development with this change. So let's create a parent patch that implements solely markNotInteresting from D104300. And that new patch should be the parent of this patch, also D104300 could be rebased once the new patch of markNotInteresting is landed.

balazske updated this revision to Diff 357947.Jul 12 2021, 8:09 AM

Using the new symbol "uninterestingness" feature.

balazske marked 4 inline comments as done.Jul 15 2021, 12:55 AM
balazske added inline comments.
clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
430–432

Problem solved: see constructSetEofNoteTag

The bug reports speak for themselves, they are awesome. Nice work!

clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
28–30

Thank you! Big fan of these.

34–35

You don't seem to reuse these in this or the followup patch? Its not a big deal, I don't mind you creating them, just feels a bit odd to me.

402

Can you not capture this as well? We could eliminate StreamChecker::Instance that way I suppose.

705–711

Oh, this took me quite a bit. Can we change SS to something that reflects that its the current error state, not the new one? Like CurrSS?

NoQ added a comment.Jul 16 2021, 7:58 PM

Looks great now!

clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
409

The word "that" looks redundant, we don't use it in any other similar notes, eg. "Assuming that 'ptr' is null" etc.

balazske updated this revision to Diff 359694.Jul 19 2021, 1:19 AM

Removed Instance, small rename, fix of warning text.

balazske marked 3 inline comments as done.Jul 19 2021, 1:20 AM
balazske added inline comments.
clang/lib/StaticAnalyzer/Checkers/StreamChecker.cpp
34–35

These remained from old version of the patch, removed.

This revision is now accepted and ready to land.Jul 19 2021, 6:36 AM
This revision was landed with ongoing or failed builds.Jul 20 2021, 11:42 PM
This revision was automatically updated to reflect the committed changes.