Tokenizer::createLinks2: fix link for >>

This commit is contained in:
Daniel Marjamäki 2018-01-01 15:20:21 +01:00
parent 03b0b35a9d
commit 1af69bd0d4
2 changed files with 28 additions and 9 deletions

View File

@ -3272,9 +3272,15 @@ void Tokenizer::createLinks2()
type.push(token);
if (!templateToken && (token->previous()->str() == "template"))
templateToken = token;
} else if (token->str() == ">") {
} else if (token->str() == ">" || token->str() == ">>") {
if (type.empty() || type.top()->str() != "<") // < and > don't match.
continue;
Token * const top1 = type.top();
type.pop();
Token * const top2 = type.empty() ? nullptr : type.top();
type.push(top1);
if (token->str() == ">>" && (!top2 || top2->str() != "<"))
continue;
if (token->next() &&
!Token::Match(token->next(), "%name%|>|&|&&|*|::|,|(|)|{|}|;|[|:") &&
!Token::Match(token->next(), "&& %name% ="))
@ -3291,13 +3297,18 @@ void Tokenizer::createLinks2()
continue;
}
Token* top = type.top();
type.pop();
if (top == templateToken)
templateToken = nullptr;
Token::createMutualLinks(top, token);
if (token->str() == ">>") {
type.pop();
type.pop();
Token::createMutualLinks(top2, token);
if (top1 == templateToken || top2 == templateToken)
templateToken = nullptr;
} else {
type.pop();
Token::createMutualLinks(top1, token);
if (top1 == templateToken)
templateToken = nullptr;
}
}
}
}
@ -8266,7 +8277,7 @@ void Tokenizer::validate() const
linkTokens.push(tok);
}
else if (Token::Match(tok, "[})]]") || (tok->str() == ">" && tok->link())) {
else if (Token::Match(tok, "[})]]") || (Token::Match(tok, ">|>>") && tok->link())) {
if (tok->link() == nullptr)
cppcheckError(tok);

View File

@ -96,6 +96,7 @@ private:
TEST_CASE(canFindMatchingBracketsOuterPair);
TEST_CASE(canFindMatchingBracketsWithTooManyClosing);
TEST_CASE(canFindMatchingBracketsWithTooManyOpening);
TEST_CASE(findClosingBracket);
TEST_CASE(expressionString);
}
@ -948,6 +949,13 @@ private:
ASSERT(t == nullptr);
}
void findClosingBracket() {
givenACodeSampleToTokenize var("template<typename X, typename...Y> struct S : public Fred<Wilma<Y...>> {}");
const Token* t = var.tokens()->next()->findClosingBracket();
ASSERT(Token::simpleMatch(t, "> struct"));
}
void expressionString() {
givenACodeSampleToTokenize var1("void f() { *((unsigned long long *)x) = 0; }");
const Token *tok1 = Token::findsimplematch(var1.tokens(), "*");