MCPcopy Create free account
hub / github.com/cppcheck-opensource/cppcheck / pointerArithmetic

Method pointerArithmetic

lib/checkbufferoverrun.cpp:467–529  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

465//---------------------------------------------------------------------------
466
467void CheckBufferOverrunImpl::pointerArithmetic()
468{
469 if (!mSettings.severity.isEnabled(Severity::portability) && !mSettings.isPremiumEnabled("pointerOutOfBounds"))
470 return;
471
472 logChecker("CheckBufferOverrun::pointerArithmetic"); // portability
473
474 for (const Token *tok = mTokenizer->tokens(); tok; tok = tok->next()) {
475 if (!Token::Match(tok, "+|-"))
476 continue;
477 if (!tok->valueType() || tok->valueType()->pointer == 0)
478 continue;
479 if (!tok->isBinaryOp())
480 continue;
481 if (!tok->astOperand1()->valueType() || !tok->astOperand2()->valueType())
482 continue;
483
484 const Token *arrayToken, *indexToken;
485 if (tok->astOperand1()->valueType()->pointer > 0) {
486 arrayToken = tok->astOperand1();
487 indexToken = tok->astOperand2();
488 } else {
489 arrayToken = tok->astOperand2();
490 indexToken = tok->astOperand1();
491 }
492
493 if (!indexToken || !indexToken->valueType() || indexToken->valueType()->pointer > 0 || !indexToken->valueType()->isIntegral())
494 continue;
495
496 std::vector<Dimension> dimensions;
497 ErrorPath errorPath;
498 bool mightBeLarger = false;
499 MathLib::bigint path = 0;
500 if (!getDimensionsEtc(arrayToken, mSettings, dimensions, errorPath, mightBeLarger, path))
501 continue;
502
503 if (tok->str() == "+") {
504 // Positive index
505 if (!mightBeLarger) { // TODO check arrays with dim 1 also
506 const std::vector<const Token *> indexTokens{indexToken};
507 const std::vector<ValueFlow::Value>& indexValues =
508 getOverrunIndexValues(tok, arrayToken, dimensions, indexTokens, path);
509 if (!indexValues.empty() && !isUnreachableOperand(tok))
510 pointerArithmeticError(tok, indexToken, &indexValues.front());
511 }
512
513 if (const ValueFlow::Value *neg = indexToken->getValueLE(-1, mSettings))
514 pointerArithmeticError(tok, indexToken, neg);
515 } else if (tok->str() == "-") {
516 if (arrayToken->variable() && arrayToken->variable()->isArgument())
517 continue;
518
519 const Token *array = arrayToken;
520 while (Token::Match(array, ".|::"))
521 array = array->astOperand2();
522 if (array->variable() && array->variable()->isArray()) {
523 const ValueFlow::Value *v = indexToken->getValueGE(1, mSettings);
524 if (v)

Callers 1

runChecksMethod · 0.80

Calls 15

getDimensionsEtcFunction · 0.85
getOverrunIndexValuesFunction · 0.85
isUnreachableOperandFunction · 0.85
isPremiumEnabledMethod · 0.80
nextMethod · 0.80
isBinaryOpMethod · 0.80
astOperand1Method · 0.80
astOperand2Method · 0.80
isIntegralMethod · 0.80
frontMethod · 0.80
getValueLEMethod · 0.80
variableMethod · 0.80

Tested by

no test coverage detected