As rightly pointed out by @NoQ, nonloc::LazyCompoundVals were only used to acquire a constructed object's region, which isn't what LazyCompoundVal was made for.
Details
- Reviewers
NoQ george.karpenkov xazax.hun rnkovacs - Commits
- rGdbabdfaca5c9: [analyzer][UninitializedObjectChecker] No longer using nonloc::LazyCompoundVal
rC344879: [analyzer][UninitializedObjectChecker] No longer using nonloc::LazyCompoundVal
rL344879: [analyzer][UninitializedObjectChecker] No longer using nonloc::LazyCompoundVal
Diff Detail
Event Timeline
Yup, looks correct to me!
lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp | ||
---|---|---|
448–450 | 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. |
lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp | ||
---|---|---|
448–450 | Ummmm that wouldn't be very nice, because... | |
460–487 | ...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? |
lib/StaticAnalyzer/Checkers/UninitializedObject/UninitializedObjectChecker.cpp | ||
---|---|---|
448–450 | 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. | |
460–487 | 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?
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.
Yup sure.
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.
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 ><
Very easy:
- Put preprocessed file that crashes into repro.cpp (.c, .m, whatever).
- 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"
- Do:
creduce repro.sh repro.cpp
- Wait until it finishes.
- 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.
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.
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.
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 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.