Dereferencing null constant (simplified token list) */
| 324 | |
| 325 | /** Dereferencing null constant (simplified token list) */ |
| 326 | void CheckNullPointerImpl::nullConstantDereference() |
| 327 | { |
| 328 | logChecker("CheckNullPointer::nullConstantDereference"); |
| 329 | |
| 330 | const SymbolDatabase *symbolDatabase = mTokenizer->getSymbolDatabase(); |
| 331 | |
| 332 | for (const Scope * scope : symbolDatabase->functionScopes) { |
| 333 | if (scope->function == nullptr || !scope->function->hasBody()) // We only look for functions with a body |
| 334 | continue; |
| 335 | |
| 336 | const Token *tok = scope->bodyStart; |
| 337 | |
| 338 | if (scope->function->isConstructor()) |
| 339 | tok = scope->function->token; // Check initialization list |
| 340 | |
| 341 | for (; tok != scope->bodyEnd; tok = tok->next()) { |
| 342 | if (isUnevaluated(tok)) |
| 343 | tok = tok->linkAt(1); |
| 344 | |
| 345 | else if (Token::simpleMatch(tok, "* 0")) { |
| 346 | if (Token::Match(tok->previous(), "return|throw|;|{|}|:|[|(|,") || tok->previous()->isOp()) { |
| 347 | nullPointerError(tok); |
| 348 | } |
| 349 | } |
| 350 | |
| 351 | else if (Token::Match(tok, "0 [") && (tok->strAt(-1) != "&" || !Token::Match(tok->linkAt(1)->next(), "[.(]"))) |
| 352 | nullPointerError(tok); |
| 353 | |
| 354 | else if (Token::Match(tok->previous(), "!!. %name% (|{") && (tok->strAt(-1) != "::" || tok->strAt(-2) == "std")) { |
| 355 | if (Token::Match(tok->tokAt(2), "0|NULL|nullptr )|}") && tok->varId()) { // constructor call |
| 356 | const Variable *var = tok->variable(); |
| 357 | if (var && !var->isPointer() && !var->isArray() && var->isStlStringType()) |
| 358 | nullPointerError(tok); |
| 359 | } else { // function call |
| 360 | const std::list<const Token *> var = parseFunctionCall(*tok, mSettings.library); |
| 361 | |
| 362 | // is one of the var items a NULL pointer? |
| 363 | for (const Token *vartok : var) { |
| 364 | if (vartok->hasKnownIntValue() && vartok->getKnownIntValue() == 0) |
| 365 | nullPointerError(vartok); |
| 366 | } |
| 367 | } |
| 368 | } else if (Token::Match(tok, "std :: string|wstring ( 0|NULL|nullptr )")) |
| 369 | nullPointerError(tok); |
| 370 | |
| 371 | else if (Token::Match(tok->previous(), "::|. %name% (")) { |
| 372 | const std::vector<const Token *> &args = getArguments(tok); |
| 373 | for (int argnr = 0; argnr < args.size(); ++argnr) { |
| 374 | const Token *argtok = args[argnr]; |
| 375 | if (!argtok->hasKnownIntValue()) |
| 376 | continue; |
| 377 | if (argtok->getKnownIntValue() != 0) |
| 378 | continue; |
| 379 | if (mSettings.library.isnullargbad(tok, argnr+1)) |
| 380 | nullPointerError(argtok); |
| 381 | } |
| 382 | } |
| 383 |
no test coverage detected