library: improved handling of noreturn. The Tokenizer::isScopeNoReturn will now try to use the library to determine if scope is noreturn.
This commit is contained in:
parent
7d237579c9
commit
b2f6e9e3eb
|
@ -33,7 +33,7 @@ Library::Library() : allocid(0)
|
|||
_dealloc["fclose"] = allocid;
|
||||
}
|
||||
|
||||
Library::Library(const Library &lib) : use(lib.use), ignore(lib.ignore), noreturn(lib.noreturn), allocid(lib.allocid), _alloc(lib._alloc), _dealloc(lib._dealloc)
|
||||
Library::Library(const Library &lib) : use(lib.use), ignore(lib.ignore), allocid(lib.allocid), _alloc(lib._alloc), _dealloc(lib._dealloc), _noreturn(lib._noreturn)
|
||||
{
|
||||
|
||||
}
|
||||
|
@ -69,9 +69,28 @@ bool Library::load(const char path[])
|
|||
|
||||
else if (strcmp(node->Name(),"ignore")==0)
|
||||
ignore.insert(node->GetText());
|
||||
else if (strcmp(node->Name(),"noreturn")==0)
|
||||
noreturn.insert(node->GetText());
|
||||
else
|
||||
else if (strcmp(node->Name(),"function")==0) {
|
||||
const char *name = node->Attribute("name");
|
||||
if (name == NULL)
|
||||
return false;
|
||||
|
||||
for (const tinyxml2::XMLElement *functionnode = node->FirstChildElement(); functionnode; functionnode = functionnode->NextSiblingElement()) {
|
||||
if (strcmp(functionnode->Name(),"noreturn")==0)
|
||||
_noreturn[name] = (strcmp(functionnode->GetText(), "true") == 0);
|
||||
else if (strcmp(functionnode->Name(),"arg")==0 && functionnode->Attribute("nr") != NULL) {
|
||||
const int nr = atoi(functionnode->Attribute("nr"));
|
||||
|
||||
const char *nullpointer = functionnode->Attribute("nullpointer");
|
||||
const char *uninitdata = functionnode->Attribute("uninitdata");
|
||||
const char *uninitderefdata = functionnode->Attribute("uninitderefdata");
|
||||
|
||||
functionArgument[name][nr].nullpointer = (nullpointer != NULL);
|
||||
functionArgument[name][nr].uninitdata = (uninitdata != NULL);
|
||||
functionArgument[name][nr].uninitderefdata = (uninitderefdata != NULL);
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
} else
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
|
@ -60,12 +60,31 @@ public:
|
|||
|
||||
std::set<std::string> use;
|
||||
std::set<std::string> ignore;
|
||||
std::set<std::string> noreturn;
|
||||
|
||||
bool isnoreturn(const std::string &name) const {
|
||||
std::map<std::string,bool>::const_iterator it = _noreturn.find(name);
|
||||
return (it != _noreturn.end() && it->second);
|
||||
}
|
||||
|
||||
bool isnotnoreturn(const std::string &name) const {
|
||||
std::map<std::string,bool>::const_iterator it = _noreturn.find(name);
|
||||
return (it != _noreturn.end() && !it->second);
|
||||
}
|
||||
|
||||
struct Argument {
|
||||
bool nullpointer;
|
||||
bool uninitdata;
|
||||
bool uninitderefdata;
|
||||
};
|
||||
|
||||
// function name, argument nr => argument data
|
||||
std::map<std::string, std::map<int, Argument> > functionArgument;
|
||||
|
||||
private:
|
||||
int allocid;
|
||||
std::map<std::string, int> _alloc; // allocation functions
|
||||
std::map<std::string, int> _dealloc; // deallocation functions
|
||||
std::map<std::string, bool> _noreturn; // is function noreturn?
|
||||
|
||||
int getid(const std::map<std::string,int> &data, const std::string &name) const {
|
||||
const std::map<std::string,int>::const_iterator it = data.find(name);
|
||||
|
|
|
@ -7731,7 +7731,7 @@ void Tokenizer::simplifyStd()
|
|||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
bool Tokenizer::IsScopeNoReturn(const Token *endScopeToken, bool *unknown)
|
||||
bool Tokenizer::IsScopeNoReturn(const Token *endScopeToken, bool *unknown) const
|
||||
{
|
||||
if (unknown)
|
||||
*unknown = false;
|
||||
|
@ -7755,6 +7755,13 @@ bool Tokenizer::IsScopeNoReturn(const Token *endScopeToken, bool *unknown)
|
|||
while (tok && (Token::Match(tok, "::|.") || tok->isName()))
|
||||
tok = tok->previous();
|
||||
|
||||
if (Token::Match(tok, "[;{}] %var% (")) {
|
||||
if (_settings->library.isnoreturn(tok->next()->str()))
|
||||
return true;
|
||||
if (_settings->library.isnotnoreturn(tok->next()->str()))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Token::Match(tok, "[;{}]")) {
|
||||
if (unknown)
|
||||
*unknown = true;
|
||||
|
|
|
@ -63,7 +63,7 @@ public:
|
|||
* \param unknown set to true if it's unknown if the scope is noreturn
|
||||
* \return true if scope ends with a function call that might be 'noreturn'
|
||||
*/
|
||||
static bool IsScopeNoReturn(const Token *endScopeToken, bool *unknown = 0);
|
||||
bool IsScopeNoReturn(const Token *endScopeToken, bool *unknown = 0) const;
|
||||
|
||||
/**
|
||||
* Tokenize code
|
||||
|
|
Loading…
Reference in New Issue