Revert "Fixed #3648 (Internal error: Token::Match called with varid 0)"
This reverts commit 1fa1ddccba
.
This commit is contained in:
parent
1fa1ddccba
commit
d6c8de104c
|
@ -620,6 +620,8 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (i->isArray() && i->isClass()) // Array of class/struct members. Initialized by ctor.
|
||||
variables.write(i->varId());
|
||||
if (i->isArray() && Token::Match(i->nameToken(), "%var% [ %var% ]")) // Array index variable read.
|
||||
variables.read(i->nameToken()->tokAt(2)->varId());
|
||||
|
||||
|
@ -706,7 +708,7 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
|
|||
}
|
||||
}
|
||||
|
||||
else if (Token::Match(tok, "return|throw %var%")) {
|
||||
else if (Token::Match(tok, "return|throw")) {
|
||||
for (const Token *tok2 = tok->next(); tok2; tok2 = tok2->next()) {
|
||||
if (tok2->varId())
|
||||
variables.readAll(tok2->varId());
|
||||
|
@ -838,7 +840,12 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
|
|||
}
|
||||
}
|
||||
|
||||
else if (Token::Match(tok, ">>|& %var%"))
|
||||
else if (Token::Match(tok, "& %var%")) {
|
||||
if (tok->previous()->isName() || tok->previous()->isNumber()) { // bitop
|
||||
variables.read(tok->next()->varId());
|
||||
} else // addressof
|
||||
variables.use(tok->next()->varId()); // use = read + write
|
||||
} else if (Token::Match(tok, ">> %var%"))
|
||||
variables.use(tok->next()->varId()); // use = read + write
|
||||
else if (Token::Match(tok, "%var% >>|&") && Token::Match(tok->previous(), "[{};:]"))
|
||||
variables.read(tok->varId());
|
||||
|
@ -865,8 +872,8 @@ void CheckUnusedVar::checkFunctionVariableUsage_iterateScopes(const Scope* const
|
|||
else if (Token::Match(tok, "%var% ."))
|
||||
variables.use(tok->varId()); // use = read + write
|
||||
|
||||
else if ((Token::Match(tok, "[(=&!]") || tok->isExtendedOp()) &&
|
||||
(Token::Match(tok->next(), "%var%") && !Token::Match(tok->next(), "true|false|new")) && tok->strAt(2) != "=")
|
||||
else if (tok->isExtendedOp() &&
|
||||
Token::Match(tok->next(), "%var%") && !Token::Match(tok->next(), "true|false|new") && tok->strAt(2) != "=")
|
||||
variables.readAll(tok->next()->varId());
|
||||
|
||||
else if (Token::Match(tok, "%var%") && (tok->next()->str() == ")" || tok->next()->isExtendedOp()))
|
||||
|
@ -994,9 +1001,9 @@ void CheckUnusedVar::checkStructMemberUsage()
|
|||
|
||||
if (Token::Match(tok, "struct|union %type% {")) {
|
||||
structname.clear();
|
||||
if (Token::simpleMatch(tok->previous(), "extern"))
|
||||
if (tok->strAt(-1) == "extern")
|
||||
continue;
|
||||
if ((!tok->previous() || Token::simpleMatch(tok->previous(), ";")) && Token::Match(tok->linkAt(2), ("} ; " + tok->strAt(1) + " %var% ;").c_str()))
|
||||
if ((!tok->previous() || tok->previous()->str() == ";") && Token::Match(tok->linkAt(2), ("} ; " + tok->strAt(1) + " %var% ;").c_str()))
|
||||
continue;
|
||||
|
||||
structname = tok->strAt(1);
|
||||
|
|
|
@ -70,6 +70,7 @@ public:
|
|||
/** @brief %Check that all struct members are used */
|
||||
void checkStructMemberUsage();
|
||||
|
||||
private:
|
||||
// Error messages..
|
||||
void unusedStructMemberError(const Token *tok, const std::string &structname, const std::string &varname);
|
||||
void unusedVariableError(const Token *tok, const std::string &varname);
|
||||
|
|
|
@ -2299,6 +2299,8 @@ bool Tokenizer::tokenize(std::istream &code,
|
|||
if (!preprocessorCondition) {
|
||||
setVarId();
|
||||
|
||||
createLinks2();
|
||||
|
||||
// Change initialisation of variable to assignment
|
||||
simplifyInitVar();
|
||||
}
|
||||
|
@ -2814,7 +2816,7 @@ void Tokenizer::setVarId()
|
|||
if (Token::Match(tok, "( %type% *|& %var% [),]") && !tok->next()->isStandardType()) {
|
||||
if (!Token::Match(tok->previous(), "%type%"))
|
||||
continue;
|
||||
if (tok->previous() && tok->previous()->str() == "return")
|
||||
if (Token::Match(tok->previous(), "return|if|while"))
|
||||
continue;
|
||||
if (tok->link() && !Token::Match(tok->link()->next(), "const| {") &&
|
||||
(!tok->link()->next() || tok->link()->next()->str() != ":"))
|
||||
|
@ -2865,7 +2867,7 @@ void Tokenizer::setVarId()
|
|||
if (tok->str() == "unsigned")
|
||||
tok = tok->next();
|
||||
|
||||
if (Token::Match(tok, "using namespace| %type% ;")) {
|
||||
if (Token::Match(tok, "using namespace %type% ;")) {
|
||||
tok = tok->next();
|
||||
continue;
|
||||
}
|
||||
|
@ -3296,6 +3298,62 @@ bool Tokenizer::createLinks()
|
|||
return true;
|
||||
}
|
||||
|
||||
void Tokenizer::createLinks2()
|
||||
{
|
||||
std::stack<const Token*> type;
|
||||
std::stack<Token*> links;
|
||||
for (Token *token = _tokens; token; token = token->next()) {
|
||||
if (token->link()) {
|
||||
if (Token::Match(token, "{|[|("))
|
||||
type.push(token);
|
||||
else if (Token::Match(token, "}|]|)")) {
|
||||
while (type.top()->str() == "<")
|
||||
type.pop();
|
||||
type.pop();
|
||||
} else
|
||||
token->link(0);
|
||||
}
|
||||
|
||||
else if (token->str() == ";")
|
||||
while (!links.empty())
|
||||
links.pop();
|
||||
else if (token->str() == "<" && token->previous() && token->previous()->isName() && !token->previous()->varId()) {
|
||||
type.push(token);
|
||||
links.push(token);
|
||||
} else if (token->str() == ">" || token->str() == ">>") {
|
||||
if (links.empty()) // < and > don't match.
|
||||
continue;
|
||||
if (token->next() && !token->next()->isName() && !Token::Match(token->next(), ">|&|*|::|,"))
|
||||
continue;
|
||||
|
||||
// Check type of open link
|
||||
if (type.empty() || type.top()->str() != "<" || (token->str() == ">>" && type.size() < 2)) {
|
||||
if (!links.empty())
|
||||
links.pop();
|
||||
continue;
|
||||
}
|
||||
const Token* top = type.top();
|
||||
type.pop();
|
||||
if (token->str() == ">>" && type.top()->str() != "<") {
|
||||
type.push(top);
|
||||
if (!links.empty())
|
||||
links.pop();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (token->str() == ">>") { // C++11 right angle bracket
|
||||
if (links.size() < 2)
|
||||
continue;
|
||||
token->str(">");
|
||||
token->insertToken(">");
|
||||
}
|
||||
|
||||
Token::createMutualLinks(links.top(), token);
|
||||
links.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Tokenizer::simplifySizeof()
|
||||
{
|
||||
for (Token *tok = _tokens; tok; tok = tok->next()) {
|
||||
|
@ -8069,17 +8127,16 @@ bool Tokenizer::validate() const
|
|||
const Token *lastTok = 0;
|
||||
for (const Token *tok = tokens(); tok; tok = tok->next()) {
|
||||
lastTok = tok;
|
||||
if (Token::Match(tok, "[{([]")) {
|
||||
if (Token::Match(tok, "[{([]") || (tok->str() == "<" && tok->link())) {
|
||||
if (tok->link() == 0) {
|
||||
cppcheckError(tok);
|
||||
return false;
|
||||
}
|
||||
|
||||
linktok.push(tok);
|
||||
continue;
|
||||
}
|
||||
|
||||
else if (Token::Match(tok, "[})]]")) {
|
||||
else if (Token::Match(tok, "[})]]") || (tok->str() == ">" && tok->link())) {
|
||||
if (tok->link() == 0) {
|
||||
cppcheckError(tok);
|
||||
return false;
|
||||
|
@ -8101,10 +8158,9 @@ bool Tokenizer::validate() const
|
|||
}
|
||||
|
||||
linktok.pop();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (tok->link() != 0) {
|
||||
else if (tok->link() != 0) {
|
||||
cppcheckError(tok);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -583,6 +583,11 @@ public:
|
|||
*/
|
||||
bool createLinks();
|
||||
|
||||
/**
|
||||
* Setup links between < and >.
|
||||
*/
|
||||
void createLinks2();
|
||||
|
||||
/** Syntax error */
|
||||
void syntaxError(const Token *tok);
|
||||
|
||||
|
|
|
@ -206,6 +206,7 @@ private:
|
|||
TEST_CASE(varid40); // ticket #3279
|
||||
TEST_CASE(varid41); // ticket #3340 (varid for union type)
|
||||
TEST_CASE(varid42); // ticket #3316 (varid for array)
|
||||
TEST_CASE(varid43);
|
||||
TEST_CASE(varid44);
|
||||
TEST_CASE(varidFunctionCall1);
|
||||
TEST_CASE(varidFunctionCall2);
|
||||
|
@ -223,7 +224,6 @@ private:
|
|||
TEST_CASE(varid_operator);
|
||||
TEST_CASE(varid_throw);
|
||||
TEST_CASE(varid_unknown_macro); // #2638 - unknown macro is not type
|
||||
TEST_CASE(varid_using); // ticket #3648
|
||||
|
||||
TEST_CASE(varidclass1);
|
||||
TEST_CASE(varidclass2);
|
||||
|
@ -3249,6 +3249,13 @@ private:
|
|||
tokenizeDebugListing(code));
|
||||
}
|
||||
|
||||
void varid43() {
|
||||
const std::string code("int main(int flag) { if(a & flag) { return 1; } }");
|
||||
ASSERT_EQUALS("\n\n##file 0\n"
|
||||
"1: int main ( int flag@1 ) { if ( a & flag@1 ) { return 1 ; } }\n",
|
||||
tokenizeDebugListing(code));
|
||||
}
|
||||
|
||||
void varid44() {
|
||||
const std::string code("class A:public B,public C,public D {};");
|
||||
ASSERT_EQUALS("\n\n##file 0\n"
|
||||
|
@ -3628,14 +3635,6 @@ private:
|
|||
ASSERT_EQUALS(expected, tokenizeDebugListing(code));
|
||||
}
|
||||
|
||||
void varid_using() {
|
||||
// #3648
|
||||
const char code[] = "using std::size_t;";
|
||||
const char expected[] = "\n\n##file 0\n"
|
||||
"1: using long ;\n";
|
||||
ASSERT_EQUALS(expected, tokenizeDebugListing(code));
|
||||
}
|
||||
|
||||
void varidclass1() {
|
||||
const std::string actual = tokenizeDebugListing(
|
||||
"class Fred\n"
|
||||
|
@ -5053,6 +5052,33 @@ private:
|
|||
ASSERT_EQUALS(true, tok->linkAt(8) == tok->tokAt(9));
|
||||
ASSERT_EQUALS(true, tok->linkAt(9) == tok->tokAt(8));
|
||||
}
|
||||
|
||||
{
|
||||
const char code[] = "bool foo(C<z> a, bar<int, x<float>>& f, int b) {\n"
|
||||
" return(a<b && b>f);\n"
|
||||
"}";
|
||||
errout.str("");
|
||||
Settings settings;
|
||||
Tokenizer tokenizer(&settings, this);
|
||||
std::istringstream istr(code);
|
||||
tokenizer.tokenize(istr, "test.cpp");
|
||||
const Token *tok = tokenizer.tokens();
|
||||
// template<
|
||||
ASSERT_EQUALS((long long)tok->tokAt(6), (long long)tok->linkAt(4));
|
||||
ASSERT_EQUALS((long long)tok->tokAt(4), (long long)tok->linkAt(6));
|
||||
|
||||
// bar<
|
||||
ASSERT_EQUALS((long long)tok->tokAt(17), (long long)tok->linkAt(10));
|
||||
ASSERT_EQUALS((long long)tok->tokAt(10), (long long)tok->linkAt(17));
|
||||
|
||||
// x<
|
||||
ASSERT_EQUALS((long long)tok->tokAt(16), (long long)tok->linkAt(14));
|
||||
ASSERT_EQUALS((long long)tok->tokAt(14), (long long)tok->linkAt(16));
|
||||
|
||||
// a<b && b>f
|
||||
ASSERT_EQUALS(0, (long long)tok->linkAt(28));
|
||||
ASSERT_EQUALS(0, (long long)tok->linkAt(32));
|
||||
}
|
||||
}
|
||||
|
||||
void removeExceptionSpecification1() {
|
||||
|
@ -5318,8 +5344,7 @@ private:
|
|||
void cpp0xtemplate2() {
|
||||
// tokenize ">>" into "> >"
|
||||
const char *code = "list<list<int>> ints;\n";
|
||||
TODO_ASSERT_EQUALS("list < list < int > > ints ;",
|
||||
"list < list < int >> ints ;", tokenizeAndStringify(code));
|
||||
ASSERT_EQUALS("list < list < int > > ints ;", tokenizeAndStringify(code));
|
||||
}
|
||||
|
||||
void cpp0xtemplate3() {
|
||||
|
|
Loading…
Reference in New Issue