Skip to content

Commit abd6c00

Browse files
committed
Integer overflow; generalized checking for nonportable code
1 parent 01c434f commit abd6c00

1 file changed

Lines changed: 50 additions & 28 deletions

File tree

lib/checktype.cpp

Lines changed: 50 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
//---------------------------------------------------------------------------
2121
#include "checktype.h"
2222

23+
#include "astutils.h"
2324
#include "mathlib.h"
2425
#include "platform.h"
2526
#include "settings.h"
@@ -229,6 +230,7 @@ void CheckType::integerOverflowError(const Token *tok, const ValueFlow::Value &v
229230
void CheckType::checkIntegerOverflowOptimisations()
230231
{
231232
// Interesting blogs:
233+
// https://www.airs.com/blog/archives/120
232234
// https://kristerw.blogspot.com/2016/02/how-undefined-signed-overflow-enables.html
233235
// https://research.checkpoint.com/2020/optout-compiler-undefined-behavior-optimizations/
234236

@@ -247,38 +249,58 @@ void CheckType::checkIntegerOverflowOptimisations()
247249
if (!Token::Match(tok, "<|<=|>=|>") || !tok->isBinaryOp())
248250
continue;
249251

250-
const std::string &cmp = tok->str();
251-
const Token * const lhs = tok->astOperand1();
252-
if (!Token::Match(lhs, "[+-]") || !lhs->isBinaryOp() || !lhs->valueType() || !lhs->valueType()->isIntegral() || lhs->valueType()->sign != ValueType::Sign::SIGNED)
253-
continue;
252+
const Token *lhsTokens[2] = {tok->astOperand1(), tok->astOperand2()};
253+
for (const Token *lhs: lhsTokens) {
254+
std::string cmp = tok->str();
255+
if (lhs == tok->astOperand2())
256+
cmp[0] = (cmp[0] == '<') ? '>' : '<';
254257

255-
const Token *expr = lhs->astOperand1();
256-
const Token *other = lhs->astOperand2();
257-
if (expr->varId() == 0 || expr->varId() != lhs->astSibling()->varId())
258-
continue;
258+
if (!Token::Match(lhs, "[+-]") || !lhs->isBinaryOp() || !lhs->valueType() || !lhs->valueType()->isIntegral() || lhs->valueType()->sign != ValueType::Sign::SIGNED)
259+
continue;
259260

260-
// x [+-] c cmp x
261-
if (other->isNumber() && other->getKnownIntValue() > 0) {
262-
bool result;
263-
if (tok->astOperand1()->str() == "+")
264-
result = (cmp == ">" || cmp == ">=");
265-
else
266-
result = (cmp == "<" || cmp == "<=");
267-
integerOverflowOptimisationError(tok, result ? "true" : "false");
268-
}
261+
const Token *exprTokens[2] = {lhs->astOperand1(), lhs->astOperand2()};
262+
for (const Token *expr: exprTokens) {
263+
if (lhs->str() == "-" && expr == lhs->astOperand2())
264+
continue; // TODO?
265+
266+
if (expr->hasKnownIntValue())
267+
continue;
268+
269+
if (!isSameExpression(mTokenizer->isCPP(),
270+
false,
271+
expr,
272+
lhs->astSibling(),
273+
mSettings->library,
274+
false,
275+
false))
276+
continue;
277+
278+
const Token * const other = expr->astSibling();
279+
280+
// x [+-] c cmp x
281+
if (other->isNumber() && other->getKnownIntValue() > 0) {
282+
bool result;
283+
if (lhs->str() == "+")
284+
result = (cmp == ">" || cmp == ">=");
285+
else
286+
result = (cmp == "<" || cmp == "<=");
287+
integerOverflowOptimisationError(tok, result ? "true" : "false");
288+
}
269289

270-
// x + y cmp x
271-
if (lhs->str() == "+" && other->varId() > 0) {
272-
const std::string result = other->str() + cmp + "0";
273-
integerOverflowOptimisationError(tok, result);
274-
}
290+
// x + y cmp x
291+
if (lhs->str() == "+" && other->varId() > 0) {
292+
const std::string result = other->str() + cmp + "0";
293+
integerOverflowOptimisationError(tok, result);
294+
}
275295

276-
// x - y cmp x
277-
if (lhs->str() == "-" && other->varId() > 0) {
278-
std::string cmp2 = cmp;
279-
cmp2[0] = (cmp[0] == '<') ? '>' : '<';
280-
const std::string result = other->str() + cmp2 + "0";
281-
integerOverflowOptimisationError(tok, result);
296+
// x - y cmp x
297+
if (lhs->str() == "-" && other->varId() > 0) {
298+
std::string cmp2 = cmp;
299+
cmp2[0] = (cmp[0] == '<') ? '>' : '<';
300+
const std::string result = other->str() + cmp2 + "0";
301+
integerOverflowOptimisationError(tok, result);
302+
}
303+
}
282304
}
283305
}
284306
}

0 commit comments

Comments
 (0)