#7089 segmentation fault (invalid code) in Tokenizer::simplifyTokenList1. Refactor some functions to accept argument as refernce instead of pointer
This commit is contained in:
parent
ebfa40c369
commit
3177d73fb0
|
@ -2493,7 +2493,7 @@ static bool setVarIdParseDeclaration(const Token **tok, const std::map<std::stri
|
||||||
|
|
||||||
|
|
||||||
static void setVarIdStructMembers(Token **tok1,
|
static void setVarIdStructMembers(Token **tok1,
|
||||||
std::map<unsigned int, std::map<std::string, unsigned int> > *structMembers,
|
std::map<unsigned int, std::map<std::string, unsigned int> >& structMembers,
|
||||||
unsigned int *_varId)
|
unsigned int *_varId)
|
||||||
{
|
{
|
||||||
Token *tok = *tok1;
|
Token *tok = *tok1;
|
||||||
|
@ -2507,7 +2507,7 @@ static void setVarIdStructMembers(Token **tok1,
|
||||||
if (TemplateSimplifier::templateParameters(tok->next()) > 0)
|
if (TemplateSimplifier::templateParameters(tok->next()) > 0)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
std::map<std::string, unsigned int>& members = (*structMembers)[struct_varid];
|
std::map<std::string, unsigned int>& members = structMembers[struct_varid];
|
||||||
const std::map<std::string, unsigned int>::iterator it = members.find(tok->str());
|
const std::map<std::string, unsigned int>::iterator it = members.find(tok->str());
|
||||||
if (it == members.end()) {
|
if (it == members.end()) {
|
||||||
members[tok->str()] = ++(*_varId);
|
members[tok->str()] = ++(*_varId);
|
||||||
|
@ -2521,11 +2521,11 @@ static void setVarIdStructMembers(Token **tok1,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void setVarIdClassDeclaration(Token * const startToken,
|
void Tokenizer::setVarIdClassDeclaration(Token * const startToken,
|
||||||
const std::map<std::string, unsigned int> &variableId,
|
const std::map<std::string, unsigned int> &variableId,
|
||||||
const unsigned int scopeStartVarId,
|
const unsigned int scopeStartVarId,
|
||||||
std::map<unsigned int, std::map<std::string,unsigned int> > *structMembers,
|
std::map<unsigned int, std::map<std::string,unsigned int> >& structMembers,
|
||||||
unsigned int *_varId)
|
unsigned int *_varId)
|
||||||
{
|
{
|
||||||
// end of scope
|
// end of scope
|
||||||
const Token * const endToken = startToken->link();
|
const Token * const endToken = startToken->link();
|
||||||
|
@ -2554,6 +2554,8 @@ static void setVarIdClassDeclaration(Token * const startToken,
|
||||||
Token::Match(tok->link(), "}|) ,|{"))
|
Token::Match(tok->link(), "}|) ,|{"))
|
||||||
initListArgLastToken = tok->link();
|
initListArgLastToken = tok->link();
|
||||||
}
|
}
|
||||||
|
if (!tok)
|
||||||
|
syntaxError(nullptr); // #7089 invalid code
|
||||||
if (tok->str() == "{") {
|
if (tok->str() == "{") {
|
||||||
if (initList && !initListArgLastToken)
|
if (initList && !initListArgLastToken)
|
||||||
initList = false;
|
initList = false;
|
||||||
|
@ -2595,7 +2597,7 @@ static void setVarIdClassFunction(const std::string &classname,
|
||||||
Token * const startToken,
|
Token * const startToken,
|
||||||
const Token * const endToken,
|
const Token * const endToken,
|
||||||
const std::map<std::string, unsigned int> &varlist,
|
const std::map<std::string, unsigned int> &varlist,
|
||||||
std::map<unsigned int, std::map<std::string, unsigned int> > *structMembers,
|
std::map<unsigned int, std::map<std::string, unsigned int> >& structMembers,
|
||||||
unsigned int *_varId)
|
unsigned int *_varId)
|
||||||
{
|
{
|
||||||
for (Token *tok2 = startToken; tok2 && tok2 != endToken; tok2 = tok2->next()) {
|
for (Token *tok2 = startToken; tok2 && tok2 != endToken; tok2 = tok2->next()) {
|
||||||
|
@ -2699,7 +2701,7 @@ void Tokenizer::setVarId()
|
||||||
setVarIdClassDeclaration(tok->link(),
|
setVarIdClassDeclaration(tok->link(),
|
||||||
variableId,
|
variableId,
|
||||||
scopeStack.top().startVarid,
|
scopeStack.top().startVarid,
|
||||||
&structMembers,
|
structMembers,
|
||||||
&_varId);
|
&_varId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2819,7 +2821,7 @@ void Tokenizer::setVarId()
|
||||||
const std::map<std::string, unsigned int>::const_iterator it = variableId.find(tok->str());
|
const std::map<std::string, unsigned int>::const_iterator it = variableId.find(tok->str());
|
||||||
if (it != variableId.end()) {
|
if (it != variableId.end()) {
|
||||||
tok->varId(it->second);
|
tok->varId(it->second);
|
||||||
setVarIdStructMembers(&tok, &structMembers, &_varId);
|
setVarIdStructMembers(&tok, structMembers, &_varId);
|
||||||
}
|
}
|
||||||
} else if (Token::Match(tok, "::|. %name%")) {
|
} else if (Token::Match(tok, "::|. %name%")) {
|
||||||
// Don't set varid after a :: or . token
|
// Don't set varid after a :: or . token
|
||||||
|
@ -2876,7 +2878,7 @@ void Tokenizer::setVarId()
|
||||||
if (tok2->link()) {
|
if (tok2->link()) {
|
||||||
if (tok2->str() == "{") {
|
if (tok2->str() == "{") {
|
||||||
if (tok2->strAt(-1) == ")" || tok2->strAt(-2) == ")")
|
if (tok2->strAt(-1) == ")" || tok2->strAt(-2) == ")")
|
||||||
setVarIdClassFunction(classname, tok2, tok2->link(), thisClassVars, &structMembers, &_varId);
|
setVarIdClassFunction(classname, tok2, tok2->link(), thisClassVars, structMembers, &_varId);
|
||||||
tok2 = tok2->link();
|
tok2 = tok2->link();
|
||||||
} else if (tok2->str() == "(" && tok2->link()->strAt(1) != "(")
|
} else if (tok2->str() == "(" && tok2->link()->strAt(1) != "(")
|
||||||
tok2 = tok2->link();
|
tok2 = tok2->link();
|
||||||
|
@ -2920,7 +2922,7 @@ void Tokenizer::setVarId()
|
||||||
// If this is a function implementation.. add it to funclist
|
// If this is a function implementation.. add it to funclist
|
||||||
Token * start = startOfFunction(tok2);
|
Token * start = startOfFunction(tok2);
|
||||||
if (start) {
|
if (start) {
|
||||||
setVarIdClassFunction(classname, start, start->link(), thisClassVars, &structMembers, &_varId);
|
setVarIdClassFunction(classname, start, start->link(), thisClassVars, structMembers, &_varId);
|
||||||
}
|
}
|
||||||
|
|
||||||
// constructor with initializer list
|
// constructor with initializer list
|
||||||
|
@ -2934,7 +2936,7 @@ void Tokenizer::setVarId()
|
||||||
tok3 = vartok->linkAt(1);
|
tok3 = vartok->linkAt(1);
|
||||||
} while (Token::Match(tok3, ")|} [:,] %name% (|{"));
|
} while (Token::Match(tok3, ")|} [:,] %name% (|{"));
|
||||||
if (Token::Match(tok3, ")|} {")) {
|
if (Token::Match(tok3, ")|} {")) {
|
||||||
setVarIdClassFunction(classname, tok2, tok3->next()->link(), thisClassVars, &structMembers, &_varId);
|
setVarIdClassFunction(classname, tok2, tok3->next()->link(), thisClassVars, structMembers, &_varId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -716,6 +716,12 @@ private:
|
||||||
|
|
||||||
void unsupportedTypedef(const Token *tok) const;
|
void unsupportedTypedef(const Token *tok) const;
|
||||||
|
|
||||||
|
void setVarIdClassDeclaration(Token * const startToken,
|
||||||
|
const std::map<std::string, unsigned int> &variableId,
|
||||||
|
const unsigned int scopeStartVarId,
|
||||||
|
std::map<unsigned int, std::map<std::string,unsigned int> >& structMembers,
|
||||||
|
unsigned int *_varId);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/** Was there templates in the code? */
|
/** Was there templates in the code? */
|
||||||
|
|
|
@ -198,6 +198,7 @@ private:
|
||||||
TEST_CASE(garbageCode147); // #7082
|
TEST_CASE(garbageCode147); // #7082
|
||||||
TEST_CASE(garbageCode148); // #7090
|
TEST_CASE(garbageCode148); // #7090
|
||||||
TEST_CASE(garbageCode149); // #7085
|
TEST_CASE(garbageCode149); // #7085
|
||||||
|
TEST_CASE(garbageCode150); // #7089
|
||||||
|
|
||||||
TEST_CASE(garbageValueFlow);
|
TEST_CASE(garbageValueFlow);
|
||||||
TEST_CASE(garbageSymbolDatabase);
|
TEST_CASE(garbageSymbolDatabase);
|
||||||
|
@ -1185,6 +1186,15 @@ private:
|
||||||
"}");
|
"}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void garbageCode150() { // #7089
|
||||||
|
ASSERT_THROW(checkCode("class A {\n"
|
||||||
|
" pl vFoo() {\n"
|
||||||
|
" A::\n"
|
||||||
|
" };\n"
|
||||||
|
" A::\n"
|
||||||
|
"}\n"), InternalError);
|
||||||
|
}
|
||||||
|
|
||||||
void garbageValueFlow() {
|
void garbageValueFlow() {
|
||||||
// #6089
|
// #6089
|
||||||
const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"
|
const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"
|
||||||
|
|
Loading…
Reference in New Issue