Our website uses cookies to enhance your browsing experience.
Accept
to the top
close form

Fill out the form in 2 simple steps below:

Your contact information:

Step 1
Congratulations! This is your promo code!

Desired license type:

Step 2
Team license
Enterprise license
** By clicking this button you agree to our Privacy Policy statement
close form
Request our prices
New License
License Renewal
--Select currency--
USD
EUR
* By clicking this button you agree to our Privacy Policy statement

close form
Free PVS‑Studio license for Microsoft MVP specialists
* By clicking this button you agree to our Privacy Policy statement

close form
To get the licence for your open-source project, please fill out this form
* By clicking this button you agree to our Privacy Policy statement

close form
I am interested to try it on the platforms:
* By clicking this button you agree to our Privacy Policy statement

close form
check circle
Message submitted.

Your message has been sent. We will email you at


If you do not see the email in your inbox, please check if it is filtered to one of the following folders:

  • Promotion
  • Updates
  • Spam

Webinar: C++ semantics - 06.11

>
>
>
Examples of errors detected by the V629…

Examples of errors detected by the V629 diagnostic

V629. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. Consider inspecting the expression.


LLVM/Clang

V629 Consider inspecting the '1U << (NumBits - 1)' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. bitstreamwriter.h 173


void EmitVBR64(uint64_t Val, unsigned NumBits) {
  if ((uint32_t)Val == Val)
    return EmitVBR((uint32_t)Val, NumBits);

  uint64_t Threshold = 1U << (NumBits-1);
  ....
}

LLVM/Clang

V629 Consider inspecting the '1U << (NumBits - 1)' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. bitstreamreader.h 362


uint64_t ReadVBR64(unsigned NumBits) {
  ....
  Result |= uint64_t(Piece & ((1U << (NumBits-1))-1))
            << NextBit;
  ....
}

LLVM/Clang

V629 Consider inspecting the '1 << shift' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. dataextractor.cpp 171


int64_t DataExtractor::getSLEB128(....) const {
  int64_t result = 0;
  ....
  // Sign bit of byte is 2nd high order bit (0x40)
  if (shift < 64 && (byte & 0x40))
    result |= -(1 << shift);
  ....
}

LLVM/Clang

V629 Consider inspecting the 'Bit->getValue() << i' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. record.cpp 248


Init *IntRecTy::convertValue(BitsInit *BI) {
  int64_t Result = 0;
  for (unsigned i = 0, e = BI->getNumBits(); i != e; ++i)
    if (....) {
      Result |= Bit->getValue() << i;
    } else {
      return 0;
    }
  return IntInit::get(Result);
}

Xpdf

V629 Consider inspecting the 'zaehler << 16' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. swftools.c 37


typedef signed long long S64;

SFIXED RFXSWF_QFIX(int zaehler, int nenner)
{
  S64 z = zaehler<<16;
  S64 a = z/(S64)nenner;
  return (SFIXED)a;
}

SeqAn

V629 Consider inspecting the '1 << BitsPerValue < TValue >::VALUE' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. tuple_bit_compressed.h 88


template <typename TValue, unsigned SIZE>
struct Tuple<TValue, SIZE, BitPacked<> >
{
  typedef typename
    BitVector_<SIZE * BitsPerValue<TValue>::VALUE>::Type
    TBitVector;

  static const __uint64 BIT_MASK =
    (1 << BitsPerValue<TValue>::VALUE) - 1;
  ....
}

Snes9x

V629 Consider inspecting the '- 1 << (64 - n)' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. sar.h 217


static inline int64 SAR (const int64 b, const int n)
{
#ifndef RIGHTSHIFT_int64_IS_SAR
  if (b < 0)
    return ((b >> n) | (-1 << (64 - n)));
#endif
  return (b >> n);
}

SMHasher

V629 Consider inspecting the '(unsigned long) d << 32' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. Platform.h 78


__inline__ unsigned long long int rdtsc()
{
#ifdef __x86_64__
  unsigned int a, d;
  __asm__ volatile ("rdtsc" : "=a" (a), "=d" (d));
  return (unsigned long)a | ((unsigned long)d << 32);
#elif defined(__i386__)
  unsigned long long int x;
  __asm__ volatile ("rdtsc" : "=A" (x));
  return x;
#else
#define NO_CYCLE_COUNTER
  return 0;
#endif
}

It may fail if the long type appears 32-bit - an overflow will occur in the "(unsigned long)d << 32" expression.


The JUCE Library

V629 Consider inspecting the 'samples << hs' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. vorbisfile.c 1676


typedef __int64 ogg_int64_t;

ogg_int64_t pcm_offset;

int ov_pcm_seek(OggVorbis_File *vf,ogg_int64_t pos){
  ....
  int hs = ....;
  long samples=....;
  ....
  vf->pcm_offset+=samples<<hs;
  ....
}

Similar errors can be found in some other places:

  • V629 Consider inspecting the 'samples << hs' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. vorbisfile.c 1998
  • V629 Consider inspecting the 'samples << hs' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. vorbisfile.c 2039

Unreal Engine 4

V629 Consider inspecting the '1 << (HashKeyShift - PoolBitShift)' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. mallocbinned.h 800


class FMallocBinned : public FMalloc
{
  ....
  /* Used to mask off the bits that have been used to
     lookup the indirect table */
  uint64 PoolMask;
  ....
  FMallocBinned(uint32 InPageSize, uint64 AddressLimit)
  {
    ....
    PoolMask = ( ( 1 << ( HashKeyShift - PoolBitShift ) ) - 1 );
    ....
  }
}

Tesseract

V629 Consider inspecting the '~0 << flag_start_bit_' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. libtesseract303 dawg.cpp 187


uinT64 letter_mask_;

void Dawg::init(....)
{
  ....
  letter_mask_ = ~(~0 << flag_start_bit_);
  ....
}

Similar errors can be found in some other places:

  • V629 Consider inspecting the '~0 << (flag_start_bit_ + 3)' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. libtesseract303 dawg.cpp 188

Bitcoin

V629 Consider inspecting the '0x80 << (8 * (vch.size() - 1))' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. script.h 169


static int64_t set_vch(const std::vector<unsigned char>& vch)
{
  if (vch.empty())
    return 0;

  int64_t result = 0;
  for (size_t i = 0; i != vch.size(); ++i)
      result |= static_cast<int64_t>(vch[i]) << 8*i;

  // If the input vector's most significant byte is 0x80,
  // remove it from the result's msb and return a negative.
  if (vch.back() & 0x80)
      return -(result & ~(0x80 << (8 * (vch.size() - 1))));

   return result;
}

Alembic

V629 Consider inspecting the '1 << iStreamID' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. StreamManager.cpp 176


void StreamManager::put( std::size_t iStreamID )
{
  ....
  // CAS (compare and swap) non locking version
  Alembic::Util::int64_t oldVal = 0;
  Alembic::Util::int64_t newVal = 0;
  ....
  oldVal = m_streams;
  newVal = oldVal | ( 1 << iStreamID ); // <=
}

TensorFlow

V629 Consider inspecting the '1 << c->Value(tree_depth)' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. unpack_path_op.cc 55


class InferenceContext {
  ....
  inline int64 Value(DimensionOrConstant d) const {
    return d.dim.IsSet() ? d.dim->value_ : d.val;
  }
  ....
}

REGISTER_OP("UnpackPath")
    .Input("path: int32")
    .Input("path_values: float")
    .Output("unpacked_path: float")
    .SetShapeFn([](InferenceContext* c) {
      ....
      int64 num_nodes = InferenceContext::kUnknownDim;
      if (c->ValueKnown(tree_depth)) {
        num_nodes = (1 << c->Value(tree_depth)) - 1;    // <=
      }
      ....
    })
....;

Android

V629 CWE-190 Consider inspecting the '1 << reg' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. RegsInfo.h 47


template <typename AddressType>
struct RegsInfo {
  ....
  uint64_t saved_reg_map = 0;
  AddressType saved_regs[64];
  ....
  inline AddressType* Save(uint32_t reg) {
    if (reg > sizeof(saved_regs) / sizeof(AddressType)) {
      abort();
    }
    saved_reg_map |= 1 << reg;
    saved_regs[reg] = (*regs)[reg];
    return &(*regs)[reg];
  }
  ....
}

LLVM/Clang

V629 [CWE-190] Consider inspecting the '~(Size - 1) << 1' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. AArch64AddressingModes.h 260


static inline bool processLogicalImmediate(uint64_t Imm, unsigned RegSize,
                                           uint64_t &Encoding) {
  ....
  unsigned Size = RegSize;
  ....
  uint64_t NImms = ~(Size-1) << 1;
  ....
}

Similar errors can be found in some other places:

  • V629 [CWE-190] Consider inspecting the 'Immr << 6' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. AArch64AddressingModes.h 269

Qemu

V629 Consider inspecting the 'n << 9' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. qemu-img.c 1839


#define BDRV_SECTOR_BITS   9
static int coroutine_fn convert_co_read(ImgConvertState *s,
                  int64_t sector_num, int nb_sectors, uint8_t *buf)
{
  uint64_t single_read_until = 0;
  int n;
  ....
  while (nb_sectors > 0) {
    ....
    uint64_t offset;
    ....
    single_read_until = offset + (n << BDRV_SECTOR_BITS);
    ....
  }
  ....
}

jsoncons

V629 Consider inspecting the '1 << k' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. bigint.hpp 744


static constexpr uint64_t basic_type_bits = sizeof(uint64_t) * 8;

uint64_t* data()
{
  return is_dynamic() ? dynamic_stor_.data_ : short_stor_.values_;
}

basic_bigint& operator<<=( uint64_t k )
{
  size_type q = (size_type)(k / basic_type_bits);
  if ( q ) // Increase common_stor_.length_ by q:
  {
    resize(length() + q);
    for (size_type i = length(); i-- > 0; )
      data()[i] = ( i < q ? 0 : data()[i - q]);
    k %= basic_type_bits;
  }
  if ( k )  // 0 < k < basic_type_bits:
  {
    uint64_t k1 = basic_type_bits - k;
    uint64_t mask = (1 << k) - 1;             // <=
    resize( length() + 1 );
    for (size_type i = length(); i-- > 0; )
    {
      data()[i] <<= k;
      if ( i > 0 )
        data()[i] |= (data()[i-1] >> k1) & mask;
      }
  }
  reduce();
  return *this;
}

Similar errors can be found in some other places:

  • V629 Consider inspecting the '1 << k' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. bigint.hpp 779

PGM-index

V629 Consider inspecting the '1 << log_s' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. sdsl.hpp 1350


template<class t_int_vec>
t_int_vec rnd_positions(uint8_t log_s, uint64_t& mask,
                        uint64_t mod=0, uint64_t seed=17)
{
  mask = (1<<log_s)-1;              // <=
  t_int_vec rands(1<<log_s ,0);
  set_random_bits(rands, seed);
  if (mod > 0) {
    util::mod(rands, mod);
  }
  return rands;
}

YTsaurus

V629 Consider inspecting the '1 << value.Data.Uint64' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. range_inferrer.cpp:378


TDivisors GetDivisors(const TSchemaColumns& columns,
                      int keyIndex,
                      TConstExpressionPtr expr)
{
  ....
  if (binaryOp->Opcode == EBinaryOp::Divide)
  {
    ....
  }
  else if (binaryOp->Opcode == EBinaryOp::RightShift)
  {
    TUnversionedValue value = literal->Value;
    value.Data.Uint64 = 1 << value.Data.Uint64;       //  <=
    value.Id = 0;
    return TDivisors{value};
  }
  ....
}

iSulad

V629 [CWE-190, CERT-INT00-C] Consider inspecting the '1 << exponent' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. cri_helpers.cc 1098


int64_t ParseBinaryQuantity(bool positive, const std::string &numStr,
                            const std::string &denomStr, int64_t &exponent,
                            Errors &error)
{
  int64_t result = 0;
  int64_t mult = 1 << exponent;
  ....
}

PPSSPP

V629 Consider inspecting the '1 << size' expression. Bit shifting of the 32-bit value with a subsequent expansion to the 64-bit type. Arm64Emitter.cpp 4298


bool ARM64FloatEmitter::TryMOVI(u8 size, ARM64Reg Rd, uint64_t elementValue)
{
  if (size == 8)
  {
    // Can always do 8.
    MOVI(size, Rd, elementValue & 0xFF);
    return true;
  }
  ....
}
....
bool ARM64FloatEmitter::TryAnyMOVI(u8 size,
                                   ARM64Reg Rd,
                                   uint64_t elementValue)
{
  // Try the original size first in case that's more optimal.
  if (TryMOVI(size, Rd, elementValue))
    return true;

  if (size != 64)
  {
    uint64_t masked = elementValue & ((1 << size) - 1);       // <=
    for (int i = size; i < 64; ++i)
    {
      value |= masked << i;
    }
  }
  ....
}

Let's take a look at the declaration of the 'masked' variable. There are two problems in this line. Let's start with bitwise shift. When size == 32 we shift the '1' literal which has the int type. The size of int is determined by the implementation, but on many platforms it is 32 bits. We get the expression 1 << 32. The behavior in this case is not defined. But there's more. We'll take a closer look at the bitwise AND operation. Let's say that shifting one to the left works fine and all 32 bits are filled correctly. However, we are doing a bitwise AND with a 64-bit variable. According to the standard, the right operand should be sign-extended to 64 bits. If the shift results in a positive number, the most significant bits will be zero when extended. So, a bitwise AND zeroes the most significant part of the 'elementValue' variable.