diff options
author | Jordan Rose <jordan_rose@apple.com> | 2013-03-01 23:03:17 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2013-03-01 23:03:17 +0000 |
commit | d764e20189dbb42b38ada383a0a159f6adc0d56c (patch) | |
tree | 7c1634f3ab8558422ebb3b1321443204b4d318f4 /lib/StaticAnalyzer/Core/RegionStore.cpp | |
parent | c98e9130bcddd0258c110d30749edd2284087e3d (diff) |
[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>
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@176388 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/RegionStore.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/RegionStore.cpp | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/lib/StaticAnalyzer/Core/RegionStore.cpp b/lib/StaticAnalyzer/Core/RegionStore.cpp index b93c10d680..82db23dd6b 100644 --- a/lib/StaticAnalyzer/Core/RegionStore.cpp +++ b/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(); |