Skip to content

Commit a788512

Browse files
committed
CTU: Refactor isUnsafeFunction
1 parent a6e227a commit a788512

5 files changed

Lines changed: 65 additions & 87 deletions

File tree

lib/checknullpointer.cpp

Lines changed: 7 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -596,55 +596,20 @@ std::string CheckNullPointer::MyFileInfo::toString() const
596596
return CTU::toString(unsafeUsage);
597597
}
598598

599-
bool CheckNullPointer::isUnsafeFunction(const Scope *scope, int argnr, const Token **tok) const
599+
static bool isUnsafeUsage(const Check *check, const Token *vartok)
600600
{
601-
const Variable * const argvar = scope->function->getArgumentVar(argnr);
602-
if (!argvar->isPointer())
603-
return false;
604-
for (const Token *tok2 = scope->bodyStart; tok2 != scope->bodyEnd; tok2 = tok2->next()) {
605-
if (Token::simpleMatch(tok2, ") {")) {
606-
tok2 = tok2->linkAt(1);
607-
if (Token::findmatch(tok2->link(), "return|throw", tok2))
608-
return false;
609-
if (isVariableChanged(tok2->link(), tok2, argvar->declarationId(), false, mSettings, mTokenizer->isCPP()))
610-
return false;
611-
}
612-
if (tok2->variable() != argvar)
613-
continue;
614-
if (!Token::Match(tok2->astParent(), "*|["))
615-
return false;
616-
*tok = tok2;
617-
return true;
618-
}
619-
return false;
601+
(void)check;
602+
return Token::Match(vartok->astParent(), "*|[");
620603
}
621604

622605
Check::FileInfo *CheckNullPointer::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const
623606
{
624-
const CheckNullPointer checker(tokenizer, settings, nullptr);
625-
return checker.getFileInfo();
626-
}
627-
628-
Check::FileInfo *CheckNullPointer::getFileInfo() const
629-
{
630-
const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase();
607+
const std::list<CTU::FileInfo::UnsafeUsage> &unsafeUsage = CTU::getUnsafeUsage(tokenizer, settings, nullptr, ::isUnsafeUsage);
608+
if (unsafeUsage.empty())
609+
return nullptr;
631610

632611
MyFileInfo *fileInfo = new MyFileInfo;
633-
634-
// Parse all functions in TU
635-
for (const Scope &scope : symbolDatabase->scopeList) {
636-
if (!scope.isExecutable() || scope.type != Scope::eFunction || !scope.function)
637-
continue;
638-
const Function *const function = scope.function;
639-
640-
// "Unsafe" functions unconditionally reads data before it is written..
641-
for (int argnr = 0; argnr < function->argCount(); ++argnr) {
642-
const Token *tok;
643-
if (isUnsafeFunction(&scope, argnr, &tok))
644-
fileInfo->unsafeUsage.push_back(CTU::FileInfo::UnsafeUsage(CTU::getFunctionId(mTokenizer, function), argnr+1, tok->str(), CTU::FileInfo::Location(mTokenizer,tok)));
645-
}
646-
}
647-
612+
fileInfo->unsafeUsage = unsafeUsage;
648613
return fileInfo;
649614
}
650615

lib/checknullpointer.h

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,6 @@ class CPPCHECKLIB CheckNullPointer : public Check {
101101
}
102102
void nullPointerError(const Token *tok, const std::string &varname, const ValueFlow::Value* value, bool inconclusive);
103103

104-
bool isUnsafeFunction(const Scope *scope, int argnr, const Token **tok) const;
105-
106104
/* data for multifile checking */
107105
class MyFileInfo : public Check::FileInfo {
108106
public:
@@ -114,16 +112,14 @@ class CPPCHECKLIB CheckNullPointer : public Check {
114112
};
115113

116114
/** @brief Parse current TU and extract file info */
117-
Check::FileInfo *getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const;
115+
Check::FileInfo *getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const override;
118116

119117
Check::FileInfo * loadFileInfoFromXml(const tinyxml2::XMLElement *xmlElement) const;
120118

121119
/** @brief Analyse all file infos for all TU */
122120
bool analyseWholeProgram(const CTU::FileInfo *ctu, const std::list<Check::FileInfo*> &fileInfo, const Settings& settings, ErrorLogger &errorLogger);
123121

124122
private:
125-
Check::FileInfo *getFileInfo() const;
126-
127123
/** Get error messages. Used by --errorlist */
128124
void getErrorMessages(ErrorLogger *errorLogger, const Settings *settings) const override {
129125
CheckNullPointer c(nullptr, settings, errorLogger);

lib/checkuninitvar.cpp

Lines changed: 10 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1284,56 +1284,26 @@ std::string CheckUninitVar::MyFileInfo::toString() const
12841284
return CTU::toString(unsafeUsage);
12851285
}
12861286

1287-
bool CheckUninitVar::isUnsafeFunction(const Scope *scope, int argnr, const Token **tok) const
1288-
{
1289-
const Variable * const argvar = scope->function->getArgumentVar(argnr);
1290-
if (!argvar->isPointer())
1291-
return false;
1292-
for (const Token *tok2 = scope->bodyStart; tok2 != scope->bodyEnd; tok2 = tok2->next()) {
1293-
if (Token::simpleMatch(tok2, ") {")) {
1294-
tok2 = tok2->linkAt(1);
1295-
if (Token::findmatch(tok2->link(), "return|throw", tok2))
1296-
return false;
1297-
if (isVariableChanged(tok2->link(), tok2, argvar->declarationId(), false, mSettings, mTokenizer->isCPP()))
1298-
return false;
1299-
}
1300-
if (tok2->variable() != argvar)
1301-
continue;
1302-
if (!isVariableUsage(tok2, true, Alloc::ARRAY))
1303-
return false;
1304-
*tok = tok2;
1305-
return true;
1306-
}
1307-
return false;
1308-
}
1309-
1310-
13111287
Check::FileInfo *CheckUninitVar::getFileInfo(const Tokenizer *tokenizer, const Settings *settings) const
13121288
{
13131289
const CheckUninitVar checker(tokenizer, settings, nullptr);
13141290
return checker.getFileInfo();
13151291
}
13161292

1293+
static bool isVariableUsage(const Check *check, const Token *vartok)
1294+
{
1295+
const CheckUninitVar *c = dynamic_cast<const CheckUninitVar *>(check);
1296+
return c && c->isVariableUsage(vartok, true, CheckUninitVar::Alloc::ARRAY);
1297+
}
1298+
13171299
Check::FileInfo *CheckUninitVar::getFileInfo() const
13181300
{
1319-
const SymbolDatabase * const symbolDatabase = mTokenizer->getSymbolDatabase();
1301+
const std::list<CTU::FileInfo::UnsafeUsage> &unsafeUsage = CTU::getUnsafeUsage(mTokenizer, mSettings, this, ::isVariableUsage);
1302+
if (unsafeUsage.empty())
1303+
return nullptr;
13201304

13211305
MyFileInfo *fileInfo = new MyFileInfo;
1322-
1323-
// Parse all functions in TU
1324-
for (const Scope &scope : symbolDatabase->scopeList) {
1325-
if (!scope.isExecutable() || scope.type != Scope::eFunction || !scope.function)
1326-
continue;
1327-
const Function *const function = scope.function;
1328-
1329-
// "Unsafe" functions unconditionally reads data before it is written..
1330-
for (int argnr = 0; argnr < function->argCount(); ++argnr) {
1331-
const Token *tok;
1332-
if (isUnsafeFunction(&scope, argnr, &tok))
1333-
fileInfo->unsafeUsage.push_back(CTU::FileInfo::UnsafeUsage(CTU::getFunctionId(mTokenizer, function), argnr+1, tok->str(), CTU::FileInfo::Location(mTokenizer,tok)));
1334-
}
1335-
}
1336-
1306+
fileInfo->unsafeUsage = unsafeUsage ;
13371307
return fileInfo;
13381308
}
13391309

lib/ctu.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -295,6 +295,51 @@ CTU::FileInfo *CTU::getFileInfo(const Tokenizer *tokenizer)
295295
return fileInfo;
296296
}
297297

298+
static bool isUnsafeFunction(const Tokenizer *tokenizer, const Settings *settings, const Scope *scope, int argnr, const Token **tok, const Check *check, bool (*isUnsafeUsage)(const Check *check, const Token *argtok))
299+
{
300+
const Variable * const argvar = scope->function->getArgumentVar(argnr);
301+
if (!argvar->isPointer())
302+
return false;
303+
for (const Token *tok2 = scope->bodyStart; tok2 != scope->bodyEnd; tok2 = tok2->next()) {
304+
if (Token::simpleMatch(tok2, ") {")) {
305+
tok2 = tok2->linkAt(1);
306+
if (Token::findmatch(tok2->link(), "return|throw", tok2))
307+
return false;
308+
if (isVariableChanged(tok2->link(), tok2, argvar->declarationId(), false, settings, tokenizer->isCPP()))
309+
return false;
310+
}
311+
if (tok2->variable() != argvar)
312+
continue;
313+
if (!isUnsafeUsage(check, tok2))
314+
return false;
315+
*tok = tok2;
316+
return true;
317+
}
318+
return false;
319+
}
320+
321+
std::list<CTU::FileInfo::UnsafeUsage> CTU::getUnsafeUsage(const Tokenizer *tokenizer, const Settings *settings, const Check *check, bool (*isUnsafeUsage)(const Check *check, const Token *argtok))
322+
{
323+
std::list<CTU::FileInfo::UnsafeUsage> unsafeUsage;
324+
325+
// Parse all functions in TU
326+
const SymbolDatabase * const symbolDatabase = tokenizer->getSymbolDatabase();
327+
328+
for (const Scope &scope : symbolDatabase->scopeList) {
329+
if (!scope.isExecutable() || scope.type != Scope::eFunction || !scope.function)
330+
continue;
331+
const Function *const function = scope.function;
332+
333+
// "Unsafe" functions unconditionally reads data before it is written..
334+
for (int argnr = 0; argnr < function->argCount(); ++argnr) {
335+
const Token *tok;
336+
if (isUnsafeFunction(tokenizer, settings, &scope, argnr, &tok, check, isUnsafeUsage))
337+
unsafeUsage.push_back(CTU::FileInfo::UnsafeUsage(CTU::getFunctionId(tokenizer, function), argnr+1, tok->str(), CTU::FileInfo::Location(tokenizer,tok)));
338+
}
339+
}
340+
341+
return unsafeUsage;
342+
}
298343

299344
static bool findPath(const CTU::FileInfo::FunctionCall &from,
300345
const CTU::FileInfo::UnsafeUsage &to,

lib/ctu.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ namespace CTU {
107107
/** @brief Parse current TU and extract file info */
108108
FileInfo *getFileInfo(const Tokenizer *tokenizer);
109109

110+
std::list<FileInfo::UnsafeUsage> getUnsafeUsage(const Tokenizer *tokenizer, const Settings *settings, const Check *check, bool (*isUnsafeUsage)(const Check *check, const Token *argtok));
111+
110112
std::list<FileInfo::UnsafeUsage> loadUnsafeUsageListFromXml(const tinyxml2::XMLElement *xmlElement);
111113
}
112114

0 commit comments

Comments
 (0)