📄 checkmemoryleak.cpp
字号:
else if (Token::Match(tok2, "[;{}] if assign|dealloc|use ; !!else")) { if (_settings._showAll) { erase(tok2, tok2->tokAt(3)); all = true; } else { erase(tok2, tok2->tokAt(2)); } done = false; } // Reduce "if if" => "if" else if (Token::Match(tok2, "if if")) { erase(tok2, tok2->tokAt(2)); done = false; } // Reduce "if return ; alloc ;" => "alloc ;" else if (Token::Match(tok2, "[;{}] if return ; alloc ;")) { erase(tok2, tok2->tokAt(4)); done = false; } // "[;{}] if alloc ; else return ;" => "[;{}] alloc ;" else if (Token::Match(tok2, "[;{}] if alloc ; else return ;")) { erase(tok2, tok2->tokAt(2)); // Remove "if" erase(tok2->next(), tok2->tokAt(5)); // Remove "; else return" done = false; } // Reduce "if ; else %var% ;" => "if %var% ;" else if (Token::Match(tok2->next(), "if ; else %var% ;")) { erase(tok2->next(), tok2->tokAt(4)); done = false; } // Reduce "if ; else return use ;" => "if return use ;" else if (Token::Match(tok2->next(), "if ; else return use ;")) { erase(tok2->next(), tok2->tokAt(4)); done = false; } // Reduce "if return ; if return ;" => "if return ;" else if (Token::Match(tok2->next(), "if return ; if return ;")) { erase(tok2, tok2->tokAt(4)); done = false; } // Delete first if in .. "if { dealloc|assign|use ; return ; } if return ;" else if (Token::Match(tok2, "[;{}] if { dealloc|assign|use ; return ; } if return ;")) { erase(tok2, tok2->tokAt(8)); done = false; } // Remove "if { dealloc ; callfunc ; } !!else" else if (Token::Match(tok2->next(), "if { dealloc|assign|use ; callfunc ; } !!else")) { erase(tok2, tok2->tokAt(8)); done = false; } // Reducing if.. else if (_settings._showAll) { if (Token::Match(tok2, "[;{}] if { assign|dealloc|use ; return ; } !!else")) { all = true; erase(tok2, tok2->tokAt(8)); done = false; } } continue; } // Reduce "if(var) dealloc ;" and "if(var) use ;" that is not followed by an else.. if (Token::Match(tok2, "[;{}] if(var) assign|dealloc|use ; !!else")) { erase(tok2, tok2->tokAt(2)); done = false; } // Reduce "; if(!var) alloc ; !!else" => "; dealloc ; alloc ;" if (Token::Match(tok2, "; if(!var) alloc ; !!else")) { // Remove the "if(!var)" erase(tok2, tok2->tokAt(2)); // Insert "dealloc ;" before the "alloc ;" tok2->insertToken(";"); tok2->insertToken("dealloc"); done = false; } // Remove "catch ;" if (Token::simpleMatch(tok2->next(), "catch ;")) { erase(tok2, tok2->tokAt(3)); done = false; } // Reduce "if* ;" that is not followed by an else.. if (Token::Match(tok2->next(), "if(var)|if(!var)|ifv ; !!else")) { erase(tok2, tok2->tokAt(2)); done = false; } // Reduce "else ;" => ";" if (Token::Match(tok2->next(), "else ;")) { erase(tok2, tok2->tokAt(2)); done = false; } // Delete if block: "alloc; if return use ;" if (Token::Match(tok2, "alloc ; if return use ; !!else")) { erase(tok2, tok2->tokAt(5)); done = false; } // Replace "dealloc use ;" with "dealloc ;" if (Token::Match(tok2, "dealloc use ;")) { erase(tok2, tok2->tokAt(2)); done = false; } // Remove the "if break|continue ;" that follows "dealloc ; alloc ;" if (! _settings._showAll && Token::Match(tok2, "dealloc ; alloc ; if break|continue ;")) { tok2 = tok2->next()->next()->next(); erase(tok2, tok2->tokAt(3)); done = false; } // Reduce "do { alloc ; } " => "alloc ;" // TODO: If the loop can be executed twice reduce to "loop alloc ;" instead if (Token::Match(tok2->next(), "do { alloc ; }")) { erase(tok2, tok2->tokAt(3)); erase(tok2->next()->next(), tok2->tokAt(4)); done = false; } // Reduce "loop if break ; => ";" if (Token::Match(tok2->next(), "loop if break|continue ; !!else")) { erase(tok2, tok2->tokAt(4)); done = false; } // Reduce "loop { assign|dealloc|use ; alloc ; if break ; }" to "assign|dealloc|use ; alloc ;" if (Token::Match(tok2->next(), "loop { assign|dealloc|use ; alloc ; if break|continue ; }")) { // erase "loop {" erase(tok2, tok2->tokAt(3)); // erase "if break|continue ; }" tok2 = tok2->next()->next()->next()->next(); erase(tok2, tok2->tokAt(5)); done = false; } // Replace "loop { X ; break ; }" with "X ;" if (Token::Match(tok2->next(), "loop { %var% ; break ; }")) { erase(tok2, tok2->tokAt(3)); erase(tok2->next()->next(), tok2->tokAt(6)); done = false; } // Replace "loop ;" with ";" if (Token::Match(tok2->next(), "loop ;")) { erase(tok2, tok2->tokAt(2)); done = false; } // Replace "loop !var ;" with ";" if (Token::Match(tok2->next(), "loop !var ;")) { erase(tok2, tok2->tokAt(4)); done = false; } // Replace "loop !var alloc ;" with " alloc ;" if (Token::Match(tok2->next(), "loop !var alloc ;")) { erase(tok2, tok2->tokAt(3)); done = false; } // Replace "loop if return ;" with "if return ;" if (Token::Match(tok2->next(), "loop if return")) { erase(tok2, tok2->tokAt(2)); done = false; } // Delete if block in "alloc ; if(!var) return ;" if (Token::Match(tok2, "alloc ; if(!var) return ;")) { erase(tok2, tok2->tokAt(4)); done = false; } // Delete if block: "alloc; if return use ;" if (Token::Match(tok2, "alloc ; if return use ; !!else")) { erase(tok2, tok2->tokAt(5)); done = false; } // Reduce "[;{}] return ; %var%" => "[;{}] return ;" if (Token::Match(tok2, "[;{}] return ; %var%")) { erase(tok2->next()->next(), tok2->tokAt(4)); done = false; } // Reduce "[;{}] return use ; %var%" => "[;{}] return use ;" if (Token::Match(tok2, "[;{}] return use ; %var%")) { erase(tok2->next()->next()->next(), tok2->tokAt(5)); done = false; } // Reduce "if(var) return use ;" => "return use ;" if (Token::Match(tok2->next(), "if(var) return use ; !!else")) { erase(tok2, tok2->tokAt(2)); done = false; } // Reduce "if(var) assign|dealloc|use ;" => "assign|dealloc|use ;" if (Token::Match(tok2->next(), "if(var) assign|dealloc|use ; !!else")) { erase(tok2, tok2->tokAt(2)); done = false; } // malloc - realloc => alloc ; dealloc ; alloc ; // Reduce "[;{}] alloc ; dealloc ; alloc ;" => "[;{}] alloc ;" if (Token::Match(tok2, "[;{}] alloc ; dealloc ; alloc ;")) { erase(tok2->next(), tok2->tokAt(6)); done = false; } // Reduce "if* alloc ; dealloc ;" => ";" if (Token::Match(tok2->tokAt(2), "alloc ; dealloc ;") && tok2->next()->str().find("if") == 0) { erase(tok2, tok2->tokAt(5)); done = false; } // Delete second use in "use ; use ;" while (Token::Match(tok2, "[;{}] use ; use ;")) { erase(tok2, tok2->tokAt(3)); done = false; } // Delete first part in "use ; dealloc ;" if (Token::Match(tok2, "[;{}] use ; dealloc ;")) { erase(tok2, tok2->tokAt(3)); done = false; } // Delete first part in "use ; return use ;" if (Token::Match(tok2, "[;{}] use ; return use ;")) { erase(tok2, tok2->tokAt(2)); done = false; } // Delete second case in "case ; case ;" while (Token::Match(tok2, "case ; case ;")) { erase(tok2, tok2->tokAt(3)); done = false; } // Replace switch with if (if not complicated) if (Token::Match(tok2, "switch {")) { // Right now, I just handle if there are a few case and perhaps a default. bool valid = false; bool incase = false; for (const Token * _tok = tok2->tokAt(2); _tok; _tok = _tok->next()) { if (_tok->str() == "{") break; else if (_tok->str() == "}") { valid = true; break; } else if (strncmp(_tok->aaaa(), "if", 2) == 0) break; else if (_tok->str() == "switch") break; else if (_tok->str() == "loop") break; else if (incase && Token::Match(_tok, "case")) break; incase |= Token::Match(_tok, "case"); incase &= !Token::Match(_tok, "break"); } if (!incase && valid) { done = false; tok2->str(";"); erase(tok2, tok2->tokAt(2)); tok2 = tok2->next(); bool first = true; while (Token::Match(tok2, "case") || Token::Match(tok2, "default")) { bool def = Token::Match(tok2, "default"); tok2->str(first ? "if" : "}"); if (first) { first = false; tok2->insertToken("{"); } else { // Insert "else [if] { tok2->insertToken("{"); if (! def) tok2->insertToken("if"); tok2->insertToken("else"); tok2 = tok2->next(); } while (tok2 && tok2->str() != "}" && ! Token::Match(tok2, "break ;")) tok2 = tok2->next(); if (Token::Match(tok2, "break ;")) { tok2->str(";"); tok2 = tok2->next()->next(); } } } } } }}// Check for memory leaks for a function variable.void CheckMemoryLeakClass::CheckMemoryLeak_CheckScope(const Token *Tok1, const char varname[], bool classmember, unsigned int sz){ std::list<const Token *> callstack; AllocType alloctype = No; AllocType dealloctype = No; bool all = false; const Token *result; Token *tok = getcode(Tok1, callstack, varname, alloctype, dealloctype, classmember, all, sz); //tok->printOut( "getcode result" ); // Simplify the code and check if freed memory is used.. for (Token *tok2 = tok; tok2; tok2 = tok2->next()) { while (Token::Match(tok2, "[;{}] ;")) erase(tok2, tok2->tokAt(2)); } if ((result = Token::findmatch(tok, "dealloc [;{}] use|use_ ;")) != NULL) { _errorLogger->deallocuse(_tokenizer, result->tokAt(2), varname); } // Replace "&use" with "use". Replace "use_" with ";" for (Token *tok2 = tok; tok2; tok2 = tok2->next()) { if (tok2->str() == "&use") tok2->str("use"); else if (tok2->str() == "use_") tok2->str(";"); else if (tok2->str() == "::use") // Some kind of member function usage. Not analyzed very well. tok2->str("use"); else if (tok2->str() == "recursive")
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -