From 05bac66bf0b68d40ea935383900d65365c25fb20 Mon Sep 17 00:00:00 2001 From: Mahesh Madhav Date: Wed, 23 Jul 2025 05:39:55 +0000 Subject: [PATCH 1/5] Sanitizer fix: shift exponent too large lib/vf_common.cpp:115:96: runtime error: shift exponent 18446744073709550144 is too large for 64-bit type 'long long unsigned int' lib/vf_common.cpp:116:47: runtime error: shift exponent 1919 is too large for 64-bit type 'long long unsigned int' --- lib/vf_common.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index 0498a7e303d..9c256938f49 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -38,6 +38,7 @@ #include #include #include +#include namespace ValueFlow { @@ -101,6 +102,9 @@ namespace ValueFlow if (value_size == 0) return value; + // sizeof(long long) = 8 + value_size = std::min(sizeof(long long), value_size); + const MathLib::biguint unsignedMaxValue = std::numeric_limits::max() >> ((sizeof(unsignedMaxValue) - value_size) * 8); const MathLib::biguint signBit = 1ULL << (value_size * 8 - 1); value &= unsignedMaxValue; From 3410738e5e154d1847b3e6e87aa6895f337a79ed Mon Sep 17 00:00:00 2001 From: Mahesh Madhav Date: Wed, 23 Jul 2025 05:40:40 +0000 Subject: [PATCH 2/5] Sanitizer fix: overflow in std::abs lib/token.cpp:1949:20: runtime error: signed integer overflow: -9223372036854775808 - 9223372032559808511 cannot be represented in type 'long long int' --- lib/token.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/token.cpp b/lib/token.cpp index 98f79b4bb1d..ca97769dd30 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -2015,7 +2015,11 @@ static bool isAdjacent(const ValueFlow::Value& x, const ValueFlow::Value& y) return true; if (x.valueType == ValueFlow::Value::ValueType::FLOAT) return false; - return std::abs(x.intvalue - y.intvalue) == 1; + + // original abs() is not safe against overflows: + // return std::abs(x.intvalue - y.intvalue) == 1; + return (y.intvalue != std::numeric_limits::max() && x.intvalue == y.intvalue + 1) || + (y.intvalue != std::numeric_limits::min() && x.intvalue == y.intvalue - 1); } static bool removePointValue(std::list& values, std::list::iterator& x) From 6f70d59c96397334ec3403b79e39d9b51a42c394 Mon Sep 17 00:00:00 2001 From: Mahesh Madhav Date: Wed, 23 Jul 2025 05:41:14 +0000 Subject: [PATCH 3/5] Sanitizer fix: signed integer overflow lib/infer.cpp:131:39: runtime error: signed integer overflow: 9223372036854775807 + 1 cannot be represented in type 'long long int' lib/infer.cpp:141:39: runtime error: signed integer overflow: -9223372036854775808 - 1 cannot be represented in type 'long long int' lib/infer.cpp:322:65: runtime error: signed integer overflow: 9223372036854775807 + 1 cannot be represented in type 'long long int' --- lib/infer.cpp | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/lib/infer.cpp b/lib/infer.cpp index cad0761f68b..0ee5e940e8d 100644 --- a/lib/infer.cpp +++ b/lib/infer.cpp @@ -127,8 +127,12 @@ namespace { Interval result; const ValueFlow::Value* minValue = getCompareValue(values, predicate, std::less{}); if (minValue) { - if (minValue->isImpossible() && minValue->bound == ValueFlow::Value::Bound::Upper) - result.setMinValue(minValue->intvalue + 1, minValue); + if (minValue->isImpossible() && minValue->bound == ValueFlow::Value::Bound::Upper) { + if (std::numeric_limits::max() == minValue->intvalue) + result.setMinValue(minValue->intvalue, minValue); + else + result.setMinValue(minValue->intvalue + 1, minValue); + } if (minValue->isPossible() && minValue->bound == ValueFlow::Value::Bound::Lower) result.setMinValue(minValue->intvalue, minValue); if (!minValue->isImpossible() && (minValue->bound == ValueFlow::Value::Bound::Point || minValue->isKnown()) && @@ -137,8 +141,12 @@ namespace { } const ValueFlow::Value* maxValue = getCompareValue(values, predicate, std::greater{}); if (maxValue) { - if (maxValue->isImpossible() && maxValue->bound == ValueFlow::Value::Bound::Lower) - result.setMaxValue(maxValue->intvalue - 1, maxValue); + if (maxValue->isImpossible() && maxValue->bound == ValueFlow::Value::Bound::Lower) { + if (std::numeric_limits::min() == maxValue->intvalue) + result.setMaxValue(minValue->intvalue, maxValue); + else + result.setMaxValue(maxValue->intvalue - 1, maxValue); + } if (maxValue->isPossible() && maxValue->bound == ValueFlow::Value::Bound::Upper) result.setMaxValue(maxValue->intvalue, maxValue); assert(!maxValue->isKnown()); @@ -312,14 +320,20 @@ std::vector infer(const ValuePtr& model, result.push_back(std::move(value)); } else { if (!diff.minvalue.empty()) { - ValueFlow::Value value(diff.minvalue.front() - 1); + int adder(0); + if (std::numeric_limits::min() < diff.minvalue.front()) + adder = -1; + ValueFlow::Value value(diff.minvalue.front() + adder); value.setImpossible(); value.bound = ValueFlow::Value::Bound::Upper; addToErrorPath(value, diff.minRef); result.push_back(std::move(value)); } if (!diff.maxvalue.empty()) { - ValueFlow::Value value(diff.maxvalue.front() + 1); + int adder(0); + if (std::numeric_limits::max() > diff.maxvalue.front()) + adder = 1; + ValueFlow::Value value(diff.maxvalue.front() + adder); value.setImpossible(); value.bound = ValueFlow::Value::Bound::Lower; addToErrorPath(value, diff.maxRef); From 6c02e8da0e892245c31b038b0bc0aa898ab06e90 Mon Sep 17 00:00:00 2001 From: Mahesh Madhav Date: Wed, 23 Jul 2025 17:12:05 +0000 Subject: [PATCH 4/5] Change long long to MathLib::bigint --- lib/infer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/infer.cpp b/lib/infer.cpp index 0ee5e940e8d..9703d6197f3 100644 --- a/lib/infer.cpp +++ b/lib/infer.cpp @@ -128,7 +128,7 @@ namespace { const ValueFlow::Value* minValue = getCompareValue(values, predicate, std::less{}); if (minValue) { if (minValue->isImpossible() && minValue->bound == ValueFlow::Value::Bound::Upper) { - if (std::numeric_limits::max() == minValue->intvalue) + if (std::numeric_limits::max() == minValue->intvalue) result.setMinValue(minValue->intvalue, minValue); else result.setMinValue(minValue->intvalue + 1, minValue); @@ -142,7 +142,7 @@ namespace { const ValueFlow::Value* maxValue = getCompareValue(values, predicate, std::greater{}); if (maxValue) { if (maxValue->isImpossible() && maxValue->bound == ValueFlow::Value::Bound::Lower) { - if (std::numeric_limits::min() == maxValue->intvalue) + if (std::numeric_limits::min() == maxValue->intvalue) result.setMaxValue(minValue->intvalue, maxValue); else result.setMaxValue(maxValue->intvalue - 1, maxValue); From 2f95d90d00cadeb9e531fdbaa6a31e862b26afff Mon Sep 17 00:00:00 2001 From: Mahesh Madhav Date: Thu, 24 Jul 2025 14:51:30 +0000 Subject: [PATCH 5/5] Change remaining long long to MathLib::bigint --- lib/infer.cpp | 4 ++-- lib/token.cpp | 4 ++-- lib/vf_common.cpp | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/infer.cpp b/lib/infer.cpp index 9703d6197f3..f9bd368af85 100644 --- a/lib/infer.cpp +++ b/lib/infer.cpp @@ -321,7 +321,7 @@ std::vector infer(const ValuePtr& model, } else { if (!diff.minvalue.empty()) { int adder(0); - if (std::numeric_limits::min() < diff.minvalue.front()) + if (std::numeric_limits::min() < diff.minvalue.front()) adder = -1; ValueFlow::Value value(diff.minvalue.front() + adder); value.setImpossible(); @@ -331,7 +331,7 @@ std::vector infer(const ValuePtr& model, } if (!diff.maxvalue.empty()) { int adder(0); - if (std::numeric_limits::max() > diff.maxvalue.front()) + if (std::numeric_limits::max() > diff.maxvalue.front()) adder = 1; ValueFlow::Value value(diff.maxvalue.front() + adder); value.setImpossible(); diff --git a/lib/token.cpp b/lib/token.cpp index ca97769dd30..ac836f53a04 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -2018,8 +2018,8 @@ static bool isAdjacent(const ValueFlow::Value& x, const ValueFlow::Value& y) // original abs() is not safe against overflows: // return std::abs(x.intvalue - y.intvalue) == 1; - return (y.intvalue != std::numeric_limits::max() && x.intvalue == y.intvalue + 1) || - (y.intvalue != std::numeric_limits::min() && x.intvalue == y.intvalue - 1); + return (y.intvalue != std::numeric_limits::max() && x.intvalue == y.intvalue + 1) || + (y.intvalue != std::numeric_limits::min() && x.intvalue == y.intvalue - 1); } static bool removePointValue(std::list& values, std::list::iterator& x) diff --git a/lib/vf_common.cpp b/lib/vf_common.cpp index 9c256938f49..d2cf1bffed0 100644 --- a/lib/vf_common.cpp +++ b/lib/vf_common.cpp @@ -103,7 +103,7 @@ namespace ValueFlow return value; // sizeof(long long) = 8 - value_size = std::min(sizeof(long long), value_size); + value_size = std::min(sizeof(MathLib::bigint), value_size); const MathLib::biguint unsignedMaxValue = std::numeric_limits::max() >> ((sizeof(unsignedMaxValue) - value_size) * 8); const MathLib::biguint signBit = 1ULL << (value_size * 8 - 1);