diff --git a/lib/checkbufferoverrun.cpp b/lib/checkbufferoverrun.cpp index e2cadf372..3623d623c 100644 --- a/lib/checkbufferoverrun.cpp +++ b/lib/checkbufferoverrun.cpp @@ -1286,13 +1286,14 @@ void CheckBufferOverrun::checkSprintfCall(const Token *tok, int size) CheckBufferOverrun::ArrayInfo::ArrayInfo() - : num(_num), type_size(_typesize), varname(_varname) + : num(_num), type_size(_typesize), varid(_varid), varname(_varname) { _typesize = 0; + _varid = 0; } CheckBufferOverrun::ArrayInfo::ArrayInfo(const CheckBufferOverrun::ArrayInfo &ai) - : num(_num), type_size(_typesize), varname(_varname) + : num(_num), type_size(_typesize), varid(_varid), varname(_varname) { *this = ai; } @@ -1301,18 +1302,49 @@ const CheckBufferOverrun::ArrayInfo & CheckBufferOverrun::ArrayInfo::operator=(c { if (&ai != this) { - _typesize = ai._typesize; - _num = ai._num; - _varname = ai._varname; + _typesize = ai.type_size; + _num = ai.num; + _varid = ai.varid; + _varname = ai.varname; } return *this; } -bool CheckBufferOverrun::ArrayInfo::declare(unsigned int typesize, const std::string &name, const Token *atok) +bool CheckBufferOverrun::ArrayInfo::declare(const Token *tok, const Tokenizer &tokenizer) { _num.clear(); - _typesize = typesize; - _varname = name; + _typesize = 0; + _varname.clear(); + + if (!tok->isName()) + return false; + + int ivar = 0; + if (Token::Match(tok, "%type% *| %var% [")) + ivar = 1; + else if (Token::Match(tok, "%type% %type% *| %var% [")) + ivar = 2; + else + return false; + + // Goto variable name token, get element size.. + const Token *vartok = tok->tokAt(ivar); + if (vartok->str() == "*") + { + _typesize = tokenizer.sizeOfType(vartok); + vartok = vartok->next(); + } + else + { + _typesize = tokenizer.sizeOfType(tok); + } + if (_typesize == 0) + return false; + + _varname = vartok->str(); + _varid = vartok->varId(); + + const Token *atok = vartok->tokAt(2); if (!Token::Match(atok, "%num% ] ;|[")) return false; @@ -1464,13 +1496,12 @@ void CheckBufferOverrun::executionPaths() std::map arrayInfo; for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) { - if (Token::Match(tok, "[;{}] %type% %var% [ %num% ]")) + if (Token::Match(tok, "[;{}] %type%")) { - const unsigned int varid(tok->tokAt(2)->varId()); ArrayInfo ai; - if (!ai.declare(_tokenizer->sizeOfType(tok->next()), tok->strAt(2), tok->tokAt(4))) + if (!ai.declare(tok->next(), *_tokenizer)) continue; - arrayInfo[varid] = ai; + arrayInfo[ai.varid] = ai; } } diff --git a/lib/checkbufferoverrun.h b/lib/checkbufferoverrun.h index fe49b5e02..ec4d226ea 100644 --- a/lib/checkbufferoverrun.h +++ b/lib/checkbufferoverrun.h @@ -108,6 +108,9 @@ public: /** size of each element in array */ unsigned int _typesize; + /** variable id */ + unsigned int _varid; + /** full name of variable as pattern */ std::string _varname; @@ -118,12 +121,11 @@ public: /** * Declare array - set info - * \param typesize type size in bytes - * \param varname variable name - * \param atok the index token + * \param tok first token in array declaration + * \param tokenizer The tokenizer (for type size) * \return success => true */ - bool declare(unsigned int typesize, const std::string &varname, const Token *atok); + bool declare(const Token *tok, const Tokenizer &tokenizer); /** array size */ const std::vector # @@ -131,6 +133,9 @@ public: /** type size in bytes */ const unsigned int &type_size; + /** Variable name */ + const unsigned int &varid; + /** Variable name */ const std::string &varname; };