1239313Sdim//===--- APSIntType.cpp - Simple record of the type of APSInts ------------===//
2239313Sdim//
3239313Sdim//                     The LLVM Compiler Infrastructure
4239313Sdim//
5239313Sdim// This file is distributed under the University of Illinois Open Source
6239313Sdim// License. See LICENSE.TXT for details.
7239313Sdim//
8239313Sdim//===----------------------------------------------------------------------===//
9239313Sdim
10239313Sdim#include "clang/StaticAnalyzer/Core/PathSensitive/APSIntType.h"
11239313Sdim
12239313Sdimusing namespace clang;
13239313Sdimusing namespace ento;
14239313Sdim
15239313SdimAPSIntType::RangeTestResultKind
16249423SdimAPSIntType::testInRange(const llvm::APSInt &Value,
17249423Sdim                        bool AllowSignConversions) const {
18249423Sdim
19239313Sdim  // Negative numbers cannot be losslessly converted to unsigned type.
20249423Sdim  if (IsUnsigned && !AllowSignConversions &&
21249423Sdim      Value.isSigned() && Value.isNegative())
22239313Sdim    return RTR_Below;
23239313Sdim
24239313Sdim  unsigned MinBits;
25249423Sdim  if (AllowSignConversions) {
26249423Sdim    if (Value.isSigned() && !IsUnsigned)
27249423Sdim      MinBits = Value.getMinSignedBits();
28249423Sdim    else
29249423Sdim      MinBits = Value.getActiveBits();
30239313Sdim
31249423Sdim  } else {
32249423Sdim    // Signed integers can be converted to signed integers of the same width
33249423Sdim    // or (if positive) unsigned integers with one fewer bit.
34249423Sdim    // Unsigned integers can be converted to unsigned integers of the same width
35249423Sdim    // or signed integers with one more bit.
36249423Sdim    if (Value.isSigned())
37249423Sdim      MinBits = Value.getMinSignedBits() - IsUnsigned;
38249423Sdim    else
39249423Sdim      MinBits = Value.getActiveBits() + !IsUnsigned;
40249423Sdim  }
41249423Sdim
42239313Sdim  if (MinBits <= BitWidth)
43239313Sdim    return RTR_Within;
44239313Sdim
45239313Sdim  if (Value.isSigned() && Value.isNegative())
46239313Sdim    return RTR_Below;
47239313Sdim  else
48239313Sdim    return RTR_Above;
49239313Sdim}
50