This fix the crash reported in https://llvm.org/bugs/show_bug.cgi?id=31173
Details
- Reviewers
dcoughlin a.sidorin zaks.anna NoQ xazax.hun - Commits
- rGcf715bd33006: [analyzer] Fix crashes in CastToStruct checker for undefined structs
rG1149166bb9d1: [analyzer] Fix crash in CastToStruct when there is no record definition
rC297187: [analyzer] Fix crashes in CastToStruct checker for undefined structs
rC295545: [analyzer] Fix crash in CastToStruct when there is no record definition
rL297187: [analyzer] Fix crashes in CastToStruct checker for undefined structs
rL295545: [analyzer] Fix crash in CastToStruct when there is no record definition
Diff Detail
- Repository
- rL LLVM
Event Timeline
Looks good. I assume the crash is in getTypeInfo(); do you have any idea what are exact prerequisites for using this method? So that there were no more crashes here.
Please, subscribe cfe-commits list on the patches as described in http://llvm.org/docs/Phabricator.html.
Thanks!
Anna
Yes. The crash happens during the getTypeInfo() call. I don't know what prerequisites are interesting to check.
The Type pointer returned by getTypePtr() must be nonnull and valid. The method clang::Type::getTypeClass() is called using that type pointer. If that returns Type::Record then the Type pointer is casted to a RecordType. And RecordType::getDecl() is called. The RecordDecl that is returned by that call is passed to getASTRecordLayout() shown below.
The crash occurs on the first assert in this code:
const ASTRecordLayout & ASTContext::getASTRecordLayout(const RecordDecl *D) const { // These asserts test different things. A record has a definition // as soon as we begin to parse the definition. That definition is // not a complete definition (which is what isDefinition() tests) // until we *finish* parsing the definition. if (D->hasExternalLexicalStorage() && !D->getDefinition()) getExternalSource()->CompleteType(const_cast<RecordDecl*>(D)); D = D->getDefinition(); assert(D && "Cannot get layout of forward declarations!"); assert(!D->isInvalidDecl() && "Cannot get layout of invalid decl!"); assert(D->isCompleteDefinition() && "Cannot layout type before complete!"); ....
I am not sure I can write testcases that prevent regressions but do you think I should add isInvalidDecl() and isCompleteDefinition() also?
I sometimes wish ASTContext methods just didn't crash :)
Oh well, let's just see if more problems show up.
lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp | ||
---|---|---|
93 ↗ | (On Diff #83062) | I think we should move the check here then. That'd avoid double-checking if ToPointeeTy is a record type (we could cast<> directly on this branch). |
Please, make sure future reviews go through cfg-dev list. See http://llvm.org/docs/Phabricator.html.
It was reported in the bugzilla report that my first fix did not fix all crashes. A new example code was provided that triggered a new crash. I have updated the patch so both crashes are fixed.
Looks like a right fix.
lib/StaticAnalyzer/Checkers/CastToStructChecker.cpp | ||
---|---|---|
93 ↗ | (On Diff #83062) | Or just hoist it out of condition? |