aboutsummaryrefslogtreecommitdiff
path: root/lib/Checker/MemRegion.cpp
diff options
context:
space:
mode:
authorZhongxing Xu <xuzhongxing@gmail.com>2010-08-02 04:56:14 +0000
committerZhongxing Xu <xuzhongxing@gmail.com>2010-08-02 04:56:14 +0000
commit7caf9b369cba6edaf6eac25121cbc65ee938f14d (patch)
treec15958f4f67e8d3df28e928c7364dd09afee792b /lib/Checker/MemRegion.cpp
parent2fe238ed293bd4bc27af9beb9fa151fad2146fa8 (diff)
Improve flat store: MemRegion::getAsOffset() computes a region's offset within
the top-level object. FlatStore now can bind and retrieve element and field regions. PR7297 is fixed by flat store. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@110020 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Checker/MemRegion.cpp')
-rw-r--r--lib/Checker/MemRegion.cpp47
1 files changed, 46 insertions, 1 deletions
diff --git a/lib/Checker/MemRegion.cpp b/lib/Checker/MemRegion.cpp
index 9cfeb7ae2b..d9c559e847 100644
--- a/lib/Checker/MemRegion.cpp
+++ b/lib/Checker/MemRegion.cpp
@@ -18,6 +18,7 @@
#include "clang/Analysis/AnalysisContext.h"
#include "clang/Analysis/Support/BumpVector.h"
#include "clang/AST/CharUnits.h"
+#include "clang/AST/RecordLayout.h"
#include "llvm/Support/raw_ostream.h"
using namespace clang;
@@ -785,7 +786,7 @@ static bool IsCompleteType(ASTContext &Ctx, QualType Ty) {
return true;
}
-RegionRawOffset ElementRegion::getAsRawOffset() const {
+RegionRawOffset ElementRegion::getAsArrayOffset() const {
CharUnits offset = CharUnits::Zero();
const ElementRegion *ER = this;
const MemRegion *superR = NULL;
@@ -827,6 +828,50 @@ RegionRawOffset ElementRegion::getAsRawOffset() const {
return RegionRawOffset(superR, offset.getQuantity());
}
+RegionOffset ElementRegion::getAsOffset() const {
+ uint64_t Offset;
+ if (const nonloc::ConcreteInt *CI = dyn_cast<nonloc::ConcreteInt>(&Index)) {
+ int64_t i = CI->getValue().getSExtValue();
+ assert(i >= 0);
+ // We cannot compute offset for incomplete types.
+ if (!IsCompleteType(getContext(), ElementType))
+ return RegionOffset(0);
+
+ CharUnits Size = getContext().getTypeSizeInChars(ElementType);
+ Offset = i * Size.getQuantity() * 8;
+ } else
+ // We cannot compute offset for symbolic index.
+ return RegionOffset(0);
+
+ // Get the offset of the super region.
+ RegionOffset SOffset = cast<SubRegion>(superRegion)->getAsOffset();
+ if (!SOffset.getRegion())
+ return RegionOffset(0);
+ else
+ return RegionOffset(SOffset.getRegion(), SOffset.getOffset() + Offset);
+}
+
+RegionOffset FieldRegion::getAsOffset() const {
+ const RecordDecl *RD = getDecl()->getParent();
+ assert(RD->isDefinition());
+ // Get the field number.
+ unsigned idx = 0;
+ for (RecordDecl::field_iterator FI = RD->field_begin(), FE = RD->field_end();
+ FI != FE; ++FI, ++idx)
+ if (getDecl() == *FI)
+ break;
+
+ const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
+ // This is offset in bits.
+ uint64_t Offset = Layout.getFieldOffset(idx);
+
+ RegionOffset SOffset = cast<SubRegion>(superRegion)->getAsOffset();
+ if (!SOffset.getRegion())
+ return RegionOffset(0);
+ else
+ return RegionOffset(SOffset.getRegion(), SOffset.getOffset() + Offset);
+}
+
//===----------------------------------------------------------------------===//
// BlockDataRegion
//===----------------------------------------------------------------------===//