diff options
author | Jordan Rose <jordan_rose@apple.com> | 2013-03-23 01:21:33 +0000 |
---|---|---|
committer | Jordan Rose <jordan_rose@apple.com> | 2013-03-23 01:21:33 +0000 |
commit | 4708b3dde86b06f40927ae9cf30a2de83949a8f2 (patch) | |
tree | e26d5cafc1dd4c77dc3273653db8b0cbe60faa50 /lib/StaticAnalyzer/Core/APSIntType.cpp | |
parent | a339cd66be6202c6e86916f52a347d0289bf2eea (diff) | |
download | clang-4708b3dde86b06f40927ae9cf30a2de83949a8f2.tar.gz |
[analyzer] Teach constraint managers about unsigned comparisons.
In C, comparisons between signed and unsigned numbers are always done in
unsigned-space. Thus, we should know that "i >= 0U" is always true, even
if 'i' is signed. Similarly, "u >= 0" is also always true, even though '0'
is signed.
Part of <rdar://problem/13239003> (false positives related to std::vector)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@177806 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/StaticAnalyzer/Core/APSIntType.cpp')
-rw-r--r-- | lib/StaticAnalyzer/Core/APSIntType.cpp | 31 |
1 files changed, 21 insertions, 10 deletions
diff --git a/lib/StaticAnalyzer/Core/APSIntType.cpp b/lib/StaticAnalyzer/Core/APSIntType.cpp index 884b0faa9e..c7e9526821 100644 --- a/lib/StaticAnalyzer/Core/APSIntType.cpp +++ b/lib/StaticAnalyzer/Core/APSIntType.cpp @@ -13,20 +13,31 @@ using namespace clang; using namespace ento; APSIntType::RangeTestResultKind -APSIntType::testInRange(const llvm::APSInt &Value) const { +APSIntType::testInRange(const llvm::APSInt &Value, + bool AllowSignConversions) const { + // Negative numbers cannot be losslessly converted to unsigned type. - if (IsUnsigned && Value.isSigned() && Value.isNegative()) + if (IsUnsigned && !AllowSignConversions && + Value.isSigned() && Value.isNegative()) return RTR_Below; - // Signed integers can be converted to signed integers of the same width - // or (if positive) unsigned integers with one fewer bit. - // Unsigned integers can be converted to unsigned integers of the same width - // or signed integers with one more bit. unsigned MinBits; - if (Value.isSigned()) - MinBits = Value.getMinSignedBits() - IsUnsigned; - else - MinBits = Value.getActiveBits() + !IsUnsigned; + if (AllowSignConversions) { + if (Value.isSigned() && !IsUnsigned) + MinBits = Value.getMinSignedBits(); + else + MinBits = Value.getActiveBits(); + + } else { + // Signed integers can be converted to signed integers of the same width + // or (if positive) unsigned integers with one fewer bit. + // Unsigned integers can be converted to unsigned integers of the same width + // or signed integers with one more bit. + if (Value.isSigned()) + MinBits = Value.getMinSignedBits() - IsUnsigned; + else + MinBits = Value.getActiveBits() + !IsUnsigned; + } if (MinBits <= BitWidth) return RTR_Within; |