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
229230void 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