summaryrefslogtreecommitdiffstats
path: root/clang/lib/StaticAnalyzer
diff options
context:
space:
mode:
authorJordan Rose <jordan_rose@apple.com>2013-03-01 23:03:17 +0000
committerJordan Rose <jordan_rose@apple.com>2013-03-01 23:03:17 +0000
commite185d73101dc6b1637ee103133cd6b07057661da (patch)
tree9c2aa045bb93b3fc0d1edfdee00494d53e2bba6f /clang/lib/StaticAnalyzer
parentd49963609d58ceaf85de6ad90170a359258a3a2c (diff)
downloadbcm5719-llvm-e185d73101dc6b1637ee103133cd6b07057661da.tar.gz
bcm5719-llvm-e185d73101dc6b1637ee103133cd6b07057661da.zip
[analyzer] Special-case bitfields when finding sub-region bindings.
Previously we were assuming that we'd never ask for the sub-region bindings of a bitfield, since a bitfield cannot have subregions. However, unification of code paths has made that assumption invalid. While we could take advantage of this by just checking for the single possible binding, it's probably better to do the right thing, so that if/when we someday support unions we'll do the right thing there, too. This fixes a handful of false positives in analyzing LLVM. <rdar://problem/13325522> llvm-svn: 176388
Diffstat (limited to 'clang/lib/StaticAnalyzer')
-rw-r--r--clang/lib/StaticAnalyzer/Core/MemRegion.cpp4
-rw-r--r--clang/lib/StaticAnalyzer/Core/RegionStore.cpp7
2 files changed, 8 insertions, 3 deletions
diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
index 12e43537aa3..b3a1e65b19a 100644
--- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -195,6 +195,10 @@ DefinedOrUnknownSVal TypedValueRegion::getExtent(SValBuilder &svalBuilder) const
}
DefinedOrUnknownSVal FieldRegion::getExtent(SValBuilder &svalBuilder) const {
+ // Force callers to deal with bitfields explicitly.
+ if (getDecl()->isBitField())
+ return UnknownVal();
+
DefinedOrUnknownSVal Extent = DeclRegion::getExtent(svalBuilder);
// A zero-length array at the end of a struct often stands for dynamically-
diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
index b93c10d680c..82db23dd6b8 100644
--- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -757,9 +757,7 @@ collectSubRegionBindings(SmallVectorImpl<BindingPair> &Bindings,
TopKey = BindingKey::Make(Top, BindingKey::Default);
}
- // This assumes the region being invalidated is char-aligned. This isn't
- // true for bitfields, but since bitfields have no subregions they shouldn't
- // be using this function anyway.
+ // Find the length (in bits) of the region being invalidated.
uint64_t Length = UINT64_MAX;
SVal Extent = Top->getExtent(SVB);
if (Optional<nonloc::ConcreteInt> ExtentCI =
@@ -768,6 +766,9 @@ collectSubRegionBindings(SmallVectorImpl<BindingPair> &Bindings,
assert(ExtentInt.isNonNegative() || ExtentInt.isUnsigned());
// Extents are in bytes but region offsets are in bits. Be careful!
Length = ExtentInt.getLimitedValue() * SVB.getContext().getCharWidth();
+ } else if (const FieldRegion *FR = dyn_cast<FieldRegion>(Top)) {
+ if (FR->getDecl()->isBitField())
+ Length = FR->getDecl()->getBitWidthValue(SVB.getContext());
}
for (ClusterBindings::iterator I = Cluster.begin(), E = Cluster.end();
OpenPOWER on IntegriCloud