This is an archive of the discontinued LLVM Phabricator instance.

[analyzer][UninitializedObjectChecker] No longer using nonloc::LazyCompoundVal
ClosedPublic

Authored by Szelethus on Aug 27 2018, 6:43 AM.

Diff Detail

Repository
rL LLVM

Event Timeline

Szelethus created this revision.Aug 27 2018, 6:43 AM
NoQ accepted this revision.Aug 28 2018, 1:17 PM

Yup, looks correct to me!

lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
448–449 ↗(On Diff #162669)

This totally needs assert(CtorDecl == Context.getStackFrame()->getDecl()). Otherwise we're in big trouble because we'll be looking into a this-region that doesn't exist on this stack frame.

On second thought, though, i guess we should put this assertion into the constructor of CXXThisRegion. I'll do this.

Also there's an overload of getCXXThis that accepts the method itself, no need to get parent.

This revision is now accepted and ready to land.Aug 28 2018, 1:17 PM
Szelethus added inline comments.Aug 29 2018, 4:22 AM
lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
448–449 ↗(On Diff #162669)

Ummmm that wouldn't be very nice, because...

456–483 ↗(On Diff #162669)

...willBeAnalyzerLater() relies on this, and it uses all sorts of constructor decls to check whether Context.getLocationContext()->getDecl() would be a subregion of another object. Are you sure that this is incorrect?

NoQ added inline comments.Aug 29 2018, 4:05 PM
lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp
448–449 ↗(On Diff #162669)

Yeah, i guess i'll have to think a bit deeper about this. I really want to prevent invalid CXXThisRegions from appearing, but it might be not that simple.

456–483 ↗(On Diff #162669)

I mean not the this-region of the object, but the CXXThisRegion itself, in which this-region is stored. It is definitely not aliased across stack frames.

Would you be comfortable me commiting this without that assert, or should I come up with a more risk-free solution?

Szelethus updated this revision to Diff 163813.Sep 4 2018, 7:28 AM

Fixed a crash where the returned region's type wasn't CXXRecordDecl. I'm not even sure how this is possible -- and unfortunately I've been unable to create a minimal (not) working example for this, and I wasn't even able to recreate the error locally. However, on the server where I could repeatedly cause a crash with the analysis of lib/AST/Expr.cpp, this fix resolved the issue.

Note that this assert failure didn't happen inside willBeAnalyzedLater, where getConstructedRegion is used with a different CXXConstructorDecl then the one on top of the stack frame.

NoQ added a comment.Sep 4 2018, 10:37 AM

Would you be comfortable me commiting this without that assert

Yup sure.

I'm not even sure how this is possible -- and unfortunately I've been unable to create a minimal (not) working example for this, and I wasn't even able to recreate the error locally.

Sounds like a test case would be great to have. Consider extracting a preprocessed file and running it under creduce, that's a great generic method for obtaining small reproducers for crashes and regressions (but not for false positives). As far as i understand, it's a crash on llvm codebase, which should be easy to re-analyze locally, even just one file, because llvm is built with cmake and dumps compilation databases, so just use clang-check on a single file, or simply append --analyze to the compilation database run-line.

This specific problem sounds elusive because it's a problem with pointer casts, and pointer casts are currently a mess. I cannot state for sure that typed this-region type must always be a record, but it's definitely a bad smell when it is't. So i recommend a quick investigation of whether the region in question is (1) well-formed and (2) correctly reflects the semantics of the program.

Szelethus planned changes to this revision.Sep 5 2018, 11:11 AM

Sounds like a test case would be great to have.

Aye. I'd be good to land this with that testcase. There are a variety of other projects I'm working on (related to the checker), and none of them depend on this patch, so I'll commit this once I figure out how to use creduce ><

NoQ added a comment.Sep 5 2018, 11:47 AM

Very easy:

  1. Put preprocessed file that crashes into repro.cpp (.c, .m, whatever).
  2. Write repro.sh as follows:
#!/bin/bash
blah/blah/path/to/clang -cc1 -analyze -blah-blah-arguments-you-need-to-cause-a-crash repro.cpp 2>&1 | grep "Any assertion message or whatever"
  1. Do:
creduce repro.sh repro.cpp
  1. Wait until it finishes.
  2. repro.cpp now contains the reduced test case.

Tip for speed:

  • The repro.sh script should be as fast as possible. Use a release+asserts build of clang.
  • Also -analyze-function top_function_that_we_analyze_when_we_crash is a great flag to add to the run-line if possible, because it'll make the test much faster; see -analyzer-display-progress to figure out how to specify the function; if it's a lambda or a block you're out of luck because you'll need to specify line number which would change during reduce; you may also fail because top-level analyses are interacting a bit, so it may fail to crash if you restrict to a function.
Szelethus added a comment.EditedSep 10 2018, 10:34 AM

There are some nasty environment issues I'm dealing with, so the main problem is the lack of a well functioning creduce, but I'll get it done eventually.

Szelethus updated this revision to Diff 168775.Oct 9 2018, 3:56 AM

Finally managed to run creduce. I added the test that caused a crash on our server, but as I said, I couldn't replicate it elsewhere.

This revision is now accepted and ready to land.Oct 9 2018, 3:56 AM

Since a good amount of time passed since this patch was made, I'll re-analyze the LLVM project with this patch rebased on trunk just to be sure that nothing breaks.

This revision was automatically updated to reflect the committed changes.