diff options
author | Devin Coughlin <dcoughlin@apple.com> | 2015-12-05 00:22:36 +0000 |
---|---|---|
committer | Devin Coughlin <dcoughlin@apple.com> | 2015-12-05 00:22:36 +0000 |
commit | 46089867de14228205009bd4991fad0e8529ecc9 (patch) | |
tree | 71e023308556e3eef4d26b9efd097dfbb65b0a27 /clang/lib/StaticAnalyzer/Core/MemRegion.cpp | |
parent | 7c6692de16f56ec562f65f508fad4e0c68f00424 (diff) | |
download | bcm5719-llvm-46089867de14228205009bd4991fad0e8529ecc9.tar.gz bcm5719-llvm-46089867de14228205009bd4991fad0e8529ecc9.zip |
[analyzer] Fix MemRegion crash casting non-struct to derived struct (PR25426).
This commit prevents MemRegion::getAsOffset() from crashing when the analyzed
program casts a symbolic region of a non-record type to some derived type and
then attempts to access a field of the base type.
rdar://problem/23458069
llvm-svn: 254806
Diffstat (limited to 'clang/lib/StaticAnalyzer/Core/MemRegion.cpp')
-rw-r--r-- | clang/lib/StaticAnalyzer/Core/MemRegion.cpp | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp index 632a381a398..ad3f396e39a 100644 --- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp +++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp @@ -1177,6 +1177,7 @@ RegionRawOffset ElementRegion::getAsArrayOffset() const { /// Returns true if \p Base is an immediate base class of \p Child static bool isImmediateBase(const CXXRecordDecl *Child, const CXXRecordDecl *Base) { + assert(Child && "Child must not be null"); // Note that we do NOT canonicalize the base class here, because // ASTRecordLayout doesn't either. If that leads us down the wrong path, // so be it; at least we won't crash. @@ -1256,18 +1257,18 @@ RegionOffset MemRegion::getAsOffset() const { if (!Child) { // We cannot compute the offset of the base class. SymbolicOffsetBase = R; - } - - if (RootIsSymbolic) { - // Base layers on symbolic regions may not be type-correct. - // Double-check the inheritance here, and revert to a symbolic offset - // if it's invalid (e.g. due to a reinterpret_cast). - if (BOR->isVirtual()) { - if (!Child->isVirtuallyDerivedFrom(BOR->getDecl())) - SymbolicOffsetBase = R; - } else { - if (!isImmediateBase(Child, BOR->getDecl())) - SymbolicOffsetBase = R; + } else { + if (RootIsSymbolic) { + // Base layers on symbolic regions may not be type-correct. + // Double-check the inheritance here, and revert to a symbolic offset + // if it's invalid (e.g. due to a reinterpret_cast). + if (BOR->isVirtual()) { + if (!Child->isVirtuallyDerivedFrom(BOR->getDecl())) + SymbolicOffsetBase = R; + } else { + if (!isImmediateBase(Child, BOR->getDecl())) + SymbolicOffsetBase = R; + } } } |