diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index ec7e9b8a0..e936e33a7 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -845,12 +845,22 @@ static std::string ShiftInt(const char cop, const Token* left, const Token* righ if (cop == '&' || cop == '|' || cop == '^') return MathLib::calculate(left->str(), right->str(), cop); - const MathLib::bigint leftInt=MathLib::toLongNumber(left->str()); - const MathLib::bigint rightInt=MathLib::toLongNumber(right->str()); + const MathLib::bigint leftInt = MathLib::toLongNumber(left->str()); + const MathLib::bigint rightInt = MathLib::toLongNumber(right->str()); + const bool rightIntIsPositive = rightInt >= 0; + const bool leftIntIsPositive = leftInt >= 0; + const bool leftOperationIsNotLeftShift = left->previous()->str() != "<<"; + const bool operandIsLeftShift = right->previous()->str() == "<<"; + if (cop == '<') { - if (left->previous()->str() != "<<" && rightInt > 0) // Ensure that its not a shift operator as used for streams + // Ensure that its not a shift operator as used for streams + if (leftOperationIsNotLeftShift && operandIsLeftShift && rightIntIsPositive) { + if (!leftIntIsPositive) { // In case the left integer is negative, e.g. -1000 << 16. Do not simplify. + return left->str() + " << " + right->str(); + } return MathLib::toString(leftInt << rightInt); - } else if (rightInt > 0) { + } + } else if (rightIntIsPositive) { return MathLib::toString(leftInt >> rightInt); } return ""; diff --git a/test/testtokenize.cpp b/test/testtokenize.cpp index 86d29cc79..7c3eae02c 100644 --- a/test/testtokenize.cpp +++ b/test/testtokenize.cpp @@ -66,6 +66,7 @@ private: TEST_CASE(tokenize29); // #5506 (segmentation fault upon invalid code) TEST_CASE(tokenize30); // #5356 (segmentation fault upon invalid code) TEST_CASE(tokenize31); // #3503 (Wrong handling of member function taking function pointer as argument) + TEST_CASE(tokenize32); // #5884 (fsanitize=undefined: left shift of negative value -10000 in lib/templatesimplifier.cpp:852:46) // don't freak out when the syntax is wrong TEST_CASE(wrong_syntax1); @@ -891,6 +892,13 @@ private: "};")); } + // #5884 - Avoid left shift of negative integer value. + void tokenize32() { + // Do not simplify negative integer left shifts. + const char * code = "void f ( ) { int max_x ; max_x = -10000 << 16 ; }"; + ASSERT_EQUALS(code, tokenizeAndStringify(code)); + } + void wrong_syntax1() { { const char code[] ="TR(kvmpio, PROTO(int rw), ARGS(rw), TP_(aa->rw;))";