Skip to content

Commit 8576ec9

Browse files
authored
MathLib: added toString() overload for big{u}int (danmar#7084)
1 parent 7396c64 commit 8576ec9

13 files changed

+72
-48
lines changed

lib/astutils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,7 +360,7 @@ static bool match(const Token *tok, const std::string &rhs)
360360
{
361361
if (tok->str() == rhs)
362362
return true;
363-
if (!tok->varId() && tok->hasKnownIntValue() && std::to_string(tok->values().front().intvalue) == rhs)
363+
if (!tok->varId() && tok->hasKnownIntValue() && MathLib::toString(tok->values().front().intvalue) == rhs)
364364
return true;
365365
return false;
366366
}

lib/checkbufferoverrun.cpp

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ static int getMinFormatStringOutputLength(const std::vector<const Token*> &param
122122
i_d_x_f_found = true;
123123
parameterLength = 1;
124124
if (inputArgNr < parameters.size() && parameters[inputArgNr]->hasKnownIntValue())
125-
parameterLength = std::to_string(parameters[inputArgNr]->getKnownIntValue()).length();
125+
parameterLength = MathLib::toString(parameters[inputArgNr]->getKnownIntValue()).length();
126126

127127
handleNextParameter = true;
128128
break;
@@ -365,7 +365,7 @@ void CheckBufferOverrun::arrayIndex()
365365
static std::string stringifyIndexes(const std::string& array, const std::vector<ValueFlow::Value>& indexValues)
366366
{
367367
if (indexValues.size() == 1)
368-
return std::to_string(indexValues[0].intvalue);
368+
return MathLib::toString(indexValues[0].intvalue);
369369

370370
std::ostringstream ret;
371371
ret << array;
@@ -386,7 +386,7 @@ static std::string arrayIndexMessage(const Token* tok,
386386
const Token* condition)
387387
{
388388
auto add_dim = [](const std::string &s, const Dimension &dim) {
389-
return s + "[" + std::to_string(dim.num) + "]";
389+
return s + "[" + MathLib::toString(dim.num) + "]";
390390
};
391391
const std::string array = std::accumulate(dimensions.cbegin(), dimensions.cend(), tok->astOperand1()->expressionString(), std::move(add_dim));
392392

@@ -533,7 +533,7 @@ void CheckBufferOverrun::pointerArithmeticError(const Token *tok, const Token *i
533533

534534
std::string errmsg;
535535
if (indexValue->condition)
536-
errmsg = "Undefined behaviour, when '" + indexToken->expressionString() + "' is " + std::to_string(indexValue->intvalue) + " the pointer arithmetic '" + tok->expressionString() + "' is out of bounds.";
536+
errmsg = "Undefined behaviour, when '" + indexToken->expressionString() + "' is " + MathLib::toString(indexValue->intvalue) + " the pointer arithmetic '" + tok->expressionString() + "' is out of bounds.";
537537
else
538538
errmsg = "Undefined behaviour, pointer arithmetic '" + tok->expressionString() + "' is out of bounds.";
539539

@@ -1027,13 +1027,13 @@ bool CheckBufferOverrun::analyseWholeProgram1(const std::map<std::string, std::l
10271027
if (type == 1) {
10281028
errorId = "ctuArrayIndex";
10291029
if (unsafeUsage.value > 0)
1030-
errmsg = "Array index out of bounds; '" + unsafeUsage.myArgumentName + "' buffer size is " + std::to_string(functionCall->callArgValue) + " and it is accessed at offset " + std::to_string(unsafeUsage.value) + ".";
1030+
errmsg = "Array index out of bounds; '" + unsafeUsage.myArgumentName + "' buffer size is " + MathLib::toString(functionCall->callArgValue) + " and it is accessed at offset " + MathLib::toString(unsafeUsage.value) + ".";
10311031
else
1032-
errmsg = "Array index out of bounds; buffer '" + unsafeUsage.myArgumentName + "' is accessed at offset " + std::to_string(unsafeUsage.value) + ".";
1032+
errmsg = "Array index out of bounds; buffer '" + unsafeUsage.myArgumentName + "' is accessed at offset " + MathLib::toString(unsafeUsage.value) + ".";
10331033
cwe = (unsafeUsage.value > 0) ? CWE_BUFFER_OVERRUN : CWE_BUFFER_UNDERRUN;
10341034
} else {
10351035
errorId = "ctuPointerArith";
1036-
errmsg = "Pointer arithmetic overflow; '" + unsafeUsage.myArgumentName + "' buffer size is " + std::to_string(functionCall->callArgValue);
1036+
errmsg = "Pointer arithmetic overflow; '" + unsafeUsage.myArgumentName + "' buffer size is " + MathLib::toString(functionCall->callArgValue);
10371037
cwe = CWE_POINTER_ARITHMETIC_OVERFLOW;
10381038
}
10391039

lib/checkcondition.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1057,7 +1057,7 @@ static bool parseComparison(const Token *comp, bool &not1, std::string &op, std:
10571057
return false;
10581058
op = invertOperatorForOperandSwap(comp->str());
10591059
if (op1->enumerator() && op1->enumerator()->value_known)
1060-
value = std::to_string(op1->enumerator()->value);
1060+
value = MathLib::toString(op1->enumerator()->value);
10611061
else
10621062
value = op1->str();
10631063
expr = op2;
@@ -1066,7 +1066,7 @@ static bool parseComparison(const Token *comp, bool &not1, std::string &op, std:
10661066
return false;
10671067
op = comp->str();
10681068
if (op2->enumerator() && op2->enumerator()->value_known)
1069-
value = std::to_string(op2->enumerator()->value);
1069+
value = MathLib::toString(op2->enumerator()->value);
10701070
else
10711071
value = op2->str();
10721072
expr = op1;
@@ -2043,7 +2043,7 @@ void CheckCondition::compareValueOutOfTypeRangeError(const Token *comparison, co
20432043
comparison,
20442044
Severity::style,
20452045
"compareValueOutOfTypeRangeError",
2046-
"Comparing expression of type '" + type + "' against value " + std::to_string(value) + ". Condition is always " + bool_to_string(result) + ".",
2046+
"Comparing expression of type '" + type + "' against value " + MathLib::toString(value) + ". Condition is always " + bool_to_string(result) + ".",
20472047
CWE398,
20482048
Certainty::normal);
20492049
}

lib/checkother.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4007,7 +4007,7 @@ void CheckOther::knownArgumentError(const Token *tok, const Token *ftok, const V
40074007
ftype = "init list ";
40084008

40094009
const char *id;
4010-
std::string errmsg = "Argument '" + expr + "' to " + ftype + fun + " is always " + std::to_string(intvalue) + ". ";
4010+
std::string errmsg = "Argument '" + expr + "' to " + ftype + fun + " is always " + MathLib::toString(intvalue) + ". ";
40114011
if (!isVariableExpressionHidden) {
40124012
id = "knownArgument";
40134013
errmsg += "It does not matter what value '" + varexpr + "' has.";

lib/checkstl.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -205,14 +205,14 @@ void CheckStl::outOfBounds()
205205
static std::string indexValueString(const ValueFlow::Value& indexValue, const std::string& containerName = emptyString)
206206
{
207207
if (indexValue.isIteratorStartValue())
208-
return "at position " + std::to_string(indexValue.intvalue) + " from the beginning";
208+
return "at position " + MathLib::toString(indexValue.intvalue) + " from the beginning";
209209
if (indexValue.isIteratorEndValue())
210-
return "at position " + std::to_string(-indexValue.intvalue) + " from the end";
211-
std::string indexString = std::to_string(indexValue.intvalue);
210+
return "at position " + MathLib::toString(-indexValue.intvalue) + " from the end";
211+
std::string indexString = MathLib::toString(indexValue.intvalue);
212212
if (indexValue.isSymbolicValue()) {
213213
indexString = containerName + ".size()";
214214
if (indexValue.intvalue != 0)
215-
indexString += "+" + std::to_string(indexValue.intvalue);
215+
indexString += "+" + MathLib::toString(indexValue.intvalue);
216216
}
217217
if (indexValue.bound == ValueFlow::Value::Bound::Lower)
218218
return "greater or equal to " + indexString;
@@ -244,11 +244,11 @@ void CheckStl::outOfBoundsError(const Token *tok, const std::string &containerNa
244244
errmsg = "Out of bounds access in expression '" + expression + "' because '$symbol' is empty.";
245245
} else if (indexValue) {
246246
if (containerSize->condition)
247-
errmsg = ValueFlow::eitherTheConditionIsRedundant(containerSize->condition) + " or size of '$symbol' can be " + std::to_string(containerSize->intvalue) + ". Expression '" + expression + "' causes access out of bounds.";
247+
errmsg = ValueFlow::eitherTheConditionIsRedundant(containerSize->condition) + " or size of '$symbol' can be " + MathLib::toString(containerSize->intvalue) + ". Expression '" + expression + "' causes access out of bounds.";
248248
else if (indexValue->condition)
249249
errmsg = ValueFlow::eitherTheConditionIsRedundant(indexValue->condition) + " or '" + index + "' can have the value " + indexValueString(*indexValue) + ". Expression '" + expression + "' causes access out of bounds.";
250250
else
251-
errmsg = "Out of bounds access in '" + expression + "', if '$symbol' size is " + std::to_string(containerSize->intvalue) + " and '" + index + "' is " + indexValueString(*indexValue);
251+
errmsg = "Out of bounds access in '" + expression + "', if '$symbol' size is " + MathLib::toString(containerSize->intvalue) + " and '" + index + "' is " + indexValueString(*indexValue);
252252
} else {
253253
// should not happen
254254
return;

lib/mathlib.cpp

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,28 @@ double MathLib::toDoubleNumber(const std::string &str)
519519
return ret;
520520
}
521521

522+
template<> std::string MathLib::toString<MathLib::bigint>(MathLib::bigint value)
523+
{
524+
#if defined(HAVE_BOOST) && defined(HAVE_BOOST_INT128)
525+
std::ostringstream result;
526+
result << value;
527+
return result.str();
528+
#else
529+
return std::to_string(value);
530+
#endif
531+
}
532+
533+
template<> std::string MathLib::toString<MathLib::biguint>(MathLib::biguint value)
534+
{
535+
#if defined(HAVE_BOOST) && defined(HAVE_BOOST_INT128)
536+
std::ostringstream result;
537+
result << value;
538+
return result.str();
539+
#else
540+
return std::to_string(value);
541+
#endif
542+
}
543+
522544
template<> std::string MathLib::toString<double>(double value)
523545
{
524546
std::ostringstream result;
@@ -1059,7 +1081,7 @@ std::string MathLib::add(const std::string & first, const std::string & second)
10591081
return (value(first) + value(second)).str();
10601082
#else
10611083
if (MathLib::isInt(first) && MathLib::isInt(second)) {
1062-
return std::to_string(toBigNumber(first) + toBigNumber(second)) + intsuffix(first, second);
1084+
return MathLib::toString(toBigNumber(first) + toBigNumber(second)) + intsuffix(first, second);
10631085
}
10641086

10651087
double d1 = toDoubleNumber(first);
@@ -1081,7 +1103,7 @@ std::string MathLib::subtract(const std::string &first, const std::string &secon
10811103
return (value(first) - value(second)).str();
10821104
#else
10831105
if (MathLib::isInt(first) && MathLib::isInt(second)) {
1084-
return std::to_string(toBigNumber(first) - toBigNumber(second)) + intsuffix(first, second);
1106+
return MathLib::toString(toBigNumber(first) - toBigNumber(second)) + intsuffix(first, second);
10851107
}
10861108

10871109
if (first == second)
@@ -1112,7 +1134,7 @@ std::string MathLib::divide(const std::string &first, const std::string &second)
11121134
throw InternalError(nullptr, "Internal Error: Division by zero");
11131135
if (a == std::numeric_limits<bigint>::min() && std::abs(b)<=1)
11141136
throw InternalError(nullptr, "Internal Error: Division overflow");
1115-
return std::to_string(toBigNumber(first) / b) + intsuffix(first, second);
1137+
return MathLib::toString(toBigNumber(first) / b) + intsuffix(first, second);
11161138
}
11171139
if (isNullValue(second)) {
11181140
if (isNullValue(first))
@@ -1129,7 +1151,7 @@ std::string MathLib::multiply(const std::string &first, const std::string &secon
11291151
return (value(first) * value(second)).str();
11301152
#else
11311153
if (MathLib::isInt(first) && MathLib::isInt(second)) {
1132-
return std::to_string(toBigNumber(first) * toBigNumber(second)) + intsuffix(first, second);
1154+
return MathLib::toString(toBigNumber(first) * toBigNumber(second)) + intsuffix(first, second);
11331155
}
11341156
return toString(toDoubleNumber(first) * toDoubleNumber(second));
11351157
#endif
@@ -1144,7 +1166,7 @@ std::string MathLib::mod(const std::string &first, const std::string &second)
11441166
const bigint b = toBigNumber(second);
11451167
if (b == 0)
11461168
throw InternalError(nullptr, "Internal Error: Division by zero");
1147-
return std::to_string(toBigNumber(first) % b) + intsuffix(first, second);
1169+
return MathLib::toString(toBigNumber(first) % b) + intsuffix(first, second);
11481170
}
11491171
return toString(std::fmod(toDoubleNumber(first),toDoubleNumber(second)));
11501172
#endif
@@ -1169,13 +1191,13 @@ std::string MathLib::calculate(const std::string &first, const std::string &seco
11691191
return MathLib::mod(first, second);
11701192

11711193
case '&':
1172-
return std::to_string(MathLib::toBigNumber(first) & MathLib::toBigNumber(second)) + intsuffix(first, second);
1194+
return MathLib::toString(MathLib::toBigNumber(first) & MathLib::toBigNumber(second)) + intsuffix(first, second);
11731195

11741196
case '|':
1175-
return std::to_string(MathLib::toBigNumber(first) | MathLib::toBigNumber(second)) + intsuffix(first, second);
1197+
return MathLib::toString(MathLib::toBigNumber(first) | MathLib::toBigNumber(second)) + intsuffix(first, second);
11761198

11771199
case '^':
1178-
return std::to_string(MathLib::toBigNumber(first) ^ MathLib::toBigNumber(second)) + intsuffix(first, second);
1200+
return MathLib::toString(MathLib::toBigNumber(first) ^ MathLib::toBigNumber(second)) + intsuffix(first, second);
11791201

11801202
default:
11811203
throw InternalError(nullptr, std::string("Unexpected action '") + action + "' in MathLib::calculate(). Please report this to Cppcheck developers.");

lib/mathlib.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@ MathLib::value operator^(const MathLib::value &v1, const MathLib::value &v2);
149149
MathLib::value operator<<(const MathLib::value &v1, const MathLib::value &v2);
150150
MathLib::value operator>>(const MathLib::value &v1, const MathLib::value &v2);
151151

152+
template<> CPPCHECKLIB std::string MathLib::toString<MathLib::bigint>(MathLib::bigint value);
153+
template<> CPPCHECKLIB std::string MathLib::toString<MathLib::biguint>(MathLib::biguint value);
152154
template<> CPPCHECKLIB std::string MathLib::toString<double>(double value);
153155

154156
/// @}

lib/symboldatabase.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1809,7 +1809,7 @@ void SymbolDatabase::setArrayDimensionsUsingValueFlow()
18091809
tokenList.addtoken(tok->str(), 0, 0, 0, false);
18101810

18111811
else if (tok->hasKnownIntValue())
1812-
tokenList.addtoken(std::to_string(tok->getKnownIntValue()), 0, 0, 0, false);
1812+
tokenList.addtoken(MathLib::toString(tok->getKnownIntValue()), 0, 0, 0, false);
18131813

18141814
else {
18151815
fail = true;

lib/templatesimplifier.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2689,7 +2689,7 @@ bool TemplateSimplifier::simplifyCalculations(Token* frontToken, const Token *ba
26892689

26902690
if (validTokenEnd(bounded, tok, backToken, 3) &&
26912691
Token::Match(tok->previous(), "(|&&|%oror% %char% %comp% %num% &&|%oror%|)")) {
2692-
tok->str(std::to_string(MathLib::toBigNumber(tok->str())));
2692+
tok->str(MathLib::toString(MathLib::toBigNumber(tok->str())));
26932693
}
26942694

26952695
if (validTokenEnd(bounded, tok, backToken, 5) &&

lib/token.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1773,12 +1773,12 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
17731773
case ValueFlow::Value::ValueType::INT:
17741774
if (tok->valueType() && tok->valueType()->sign == ValueType::UNSIGNED) {
17751775
outs += "intvalue=\"";
1776-
outs += std::to_string(static_cast<MathLib::biguint>(value.intvalue));
1776+
outs += MathLib::toString(static_cast<MathLib::biguint>(value.intvalue));
17771777
outs += '\"';
17781778
}
17791779
else {
17801780
outs += "intvalue=\"";
1781-
outs += std::to_string(value.intvalue);
1781+
outs += MathLib::toString(value.intvalue);
17821782
outs += '\"';
17831783
}
17841784
break;
@@ -1802,22 +1802,22 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
18021802
break;
18031803
case ValueFlow::Value::ValueType::BUFFER_SIZE:
18041804
outs += "buffer-size=\"";
1805-
outs += std::to_string(value.intvalue);
1805+
outs += MathLib::toString(value.intvalue);
18061806
outs += "\"";
18071807
break;
18081808
case ValueFlow::Value::ValueType::CONTAINER_SIZE:
18091809
outs += "container-size=\"";
1810-
outs += std::to_string(value.intvalue);
1810+
outs += MathLib::toString(value.intvalue);
18111811
outs += '\"';
18121812
break;
18131813
case ValueFlow::Value::ValueType::ITERATOR_START:
18141814
outs += "iterator-start=\"";
1815-
outs += std::to_string(value.intvalue);
1815+
outs += MathLib::toString(value.intvalue);
18161816
outs += '\"';
18171817
break;
18181818
case ValueFlow::Value::ValueType::ITERATOR_END:
18191819
outs += "iterator-end=\"";
1820-
outs += std::to_string(value.intvalue);
1820+
outs += MathLib::toString(value.intvalue);
18211821
outs += '\"';
18221822
break;
18231823
case ValueFlow::Value::ValueType::LIFETIME:
@@ -1836,7 +1836,7 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
18361836
outs += id_string(value.tokvalue);
18371837
outs += '\"';
18381838
outs += " symbolic-delta=\"";
1839-
outs += std::to_string(value.intvalue);
1839+
outs += MathLib::toString(value.intvalue);
18401840
outs += '\"';
18411841
break;
18421842
}
@@ -1858,7 +1858,7 @@ void Token::printValueFlow(bool xml, std::ostream &out) const
18581858
outs += " inconclusive=\"true\"";
18591859

18601860
outs += " path=\"";
1861-
outs += std::to_string(value.path);
1861+
outs += MathLib::toString(value.path);
18621862
outs += "\"";
18631863

18641864
outs += "/>\n";

0 commit comments

Comments
 (0)