* Fix #9250 (Regression: crash in gcc testsuite) * fix cppcheck warning
This commit is contained in:
parent
cb0b057595
commit
c6c50567cf
|
@ -3436,12 +3436,11 @@ void TemplateSimplifier::simplifyTemplates(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mTokenizer->calculateScopes();
|
||||||
|
|
||||||
unsigned int passCount = 0;
|
unsigned int passCount = 0;
|
||||||
const unsigned int passCountMax = 10;
|
const unsigned int passCountMax = 10;
|
||||||
for (; passCount < passCountMax; ++passCount) {
|
for (; passCount < passCountMax; ++passCount) {
|
||||||
for (auto tok = mTokenizer->list.front(); tok; tok = tok->next()) tok->scopeInfo(nullptr);
|
|
||||||
mTokenizer->calculateScopes();
|
|
||||||
|
|
||||||
if (passCount) {
|
if (passCount) {
|
||||||
// it may take more than one pass to simplify type aliases
|
// it may take more than one pass to simplify type aliases
|
||||||
bool usingChanged = false;
|
bool usingChanged = false;
|
||||||
|
|
|
@ -2836,41 +2836,28 @@ void Tokenizer::simplifyCaseRange()
|
||||||
|
|
||||||
void Tokenizer::calculateScopes()
|
void Tokenizer::calculateScopes()
|
||||||
{
|
{
|
||||||
std::string nextScopeNameAddition = "";
|
for (auto tok = list.front(); tok; tok = tok->next())
|
||||||
|
tok->scopeInfo(nullptr);
|
||||||
|
|
||||||
if (!list.front()->scopeInfo()) {
|
std::string nextScopeNameAddition = "";
|
||||||
std::shared_ptr<ScopeInfo2> primaryScope = std::make_shared<ScopeInfo2>("", list.back());
|
std::shared_ptr<ScopeInfo2> primaryScope = std::make_shared<ScopeInfo2>("", nullptr);
|
||||||
list.front()->scopeInfo(primaryScope);
|
list.front()->scopeInfo(primaryScope);
|
||||||
|
|
||||||
|
|
||||||
if (Token::Match(list.front(), "using namespace %name% ::|<|;")) {
|
|
||||||
std::string usingNamespaceName = "";
|
|
||||||
for (const Token* namespaceNameToken = list.front()->tokAt(2); !Token::simpleMatch(namespaceNameToken, ";"); namespaceNameToken = namespaceNameToken->next()) {
|
|
||||||
usingNamespaceName += namespaceNameToken->str();
|
|
||||||
usingNamespaceName += " ";
|
|
||||||
}
|
|
||||||
if (usingNamespaceName.length() > 0) usingNamespaceName = usingNamespaceName.substr(0, usingNamespaceName.length() - 1);
|
|
||||||
list.front()->scopeInfo()->usingNamespaces.insert(usingNamespaceName);
|
|
||||||
} else if (Token::Match(list.front(), "namespace|class|struct|union %name% {|::|:|<")) {
|
|
||||||
for (Token* nameTok = list.front()->next(); nameTok && !Token::Match(nameTok, "{|:|<"); nameTok = nameTok->next()) {
|
|
||||||
nextScopeNameAddition.append(nameTok->str());
|
|
||||||
nextScopeNameAddition.append(" ");
|
|
||||||
}
|
|
||||||
if (nextScopeNameAddition.length() > 0) nextScopeNameAddition = nextScopeNameAddition.substr(0, nextScopeNameAddition.length() - 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (Token* tok = list.front(); tok; tok = tok->next()) {
|
for (Token* tok = list.front(); tok; tok = tok->next()) {
|
||||||
if (!tok->scopeInfo()) {
|
if (tok == list.front() || !tok->scopeInfo()) {
|
||||||
|
if (tok != list.front())
|
||||||
tok->scopeInfo(tok->previous()->scopeInfo());
|
tok->scopeInfo(tok->previous()->scopeInfo());
|
||||||
|
|
||||||
if (Token::Match(tok, "using namespace %name% ::|<|;")) {
|
if (Token::Match(tok, "using namespace %name% ::|<|;")) {
|
||||||
std::string usingNamespaceName = "";
|
std::string usingNamespaceName = "";
|
||||||
for (const Token* namespaceNameToken = tok->tokAt(2); !Token::simpleMatch(namespaceNameToken, ";"); namespaceNameToken = namespaceNameToken->next()) {
|
for (const Token* namespaceNameToken = tok->tokAt(2);
|
||||||
|
!Token::simpleMatch(namespaceNameToken, ";");
|
||||||
|
namespaceNameToken = namespaceNameToken->next()) {
|
||||||
usingNamespaceName += namespaceNameToken->str();
|
usingNamespaceName += namespaceNameToken->str();
|
||||||
usingNamespaceName += " ";
|
usingNamespaceName += " ";
|
||||||
}
|
}
|
||||||
if (usingNamespaceName.length() > 0) usingNamespaceName = usingNamespaceName.substr(0, usingNamespaceName.length() - 1);
|
if (usingNamespaceName.length() > 0)
|
||||||
|
usingNamespaceName = usingNamespaceName.substr(0, usingNamespaceName.length() - 1);
|
||||||
tok->scopeInfo()->usingNamespaces.insert(usingNamespaceName);
|
tok->scopeInfo()->usingNamespaces.insert(usingNamespaceName);
|
||||||
} else if (Token::Match(tok, "namespace|class|struct|union %name% {|::|:|<")) {
|
} else if (Token::Match(tok, "namespace|class|struct|union %name% {|::|:|<")) {
|
||||||
for (Token* nameTok = tok->next(); nameTok && !Token::Match(nameTok, "{|:"); nameTok = nameTok->next()) {
|
for (Token* nameTok = tok->next(); nameTok && !Token::Match(nameTok, "{|:"); nameTok = nameTok->next()) {
|
||||||
|
@ -2881,7 +2868,8 @@ void Tokenizer::calculateScopes()
|
||||||
nextScopeNameAddition.append(nameTok->str());
|
nextScopeNameAddition.append(nameTok->str());
|
||||||
nextScopeNameAddition.append(" ");
|
nextScopeNameAddition.append(" ");
|
||||||
}
|
}
|
||||||
if (nextScopeNameAddition.length() > 0) nextScopeNameAddition = nextScopeNameAddition.substr(0, nextScopeNameAddition.length() - 1);
|
if (nextScopeNameAddition.length() > 0)
|
||||||
|
nextScopeNameAddition = nextScopeNameAddition.substr(0, nextScopeNameAddition.length() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Token::simpleMatch(tok, "{")) {
|
if (Token::simpleMatch(tok, "{")) {
|
||||||
|
@ -2890,18 +2878,20 @@ void Tokenizer::calculateScopes()
|
||||||
while (Token::Match(tok1->previous(), "const|volatile|final|override|&|&&|noexcept"))
|
while (Token::Match(tok1->previous(), "const|volatile|final|override|&|&&|noexcept"))
|
||||||
tok1 = tok1->previous();
|
tok1 = tok1->previous();
|
||||||
if (tok1 && tok1->previous() && tok1->strAt(-1) == ")") {
|
if (tok1 && tok1->previous() && tok1->strAt(-1) == ")") {
|
||||||
|
bool member = true;
|
||||||
tok1 = tok1->linkAt(-1);
|
tok1 = tok1->linkAt(-1);
|
||||||
if (Token::Match(tok1->previous(), "throw|noexcept")) {
|
if (Token::Match(tok1->previous(), "throw|noexcept")) {
|
||||||
tok1 = tok1->previous();
|
tok1 = tok1->previous();
|
||||||
while (Token::Match(tok1->previous(), "const|volatile|final|override|&|&&|noexcept"))
|
while (Token::Match(tok1->previous(), "const|volatile|final|override|&|&&|noexcept"))
|
||||||
tok1 = tok1->previous();
|
tok1 = tok1->previous();
|
||||||
if (tok1->strAt(-1) != ")")
|
if (tok1->strAt(-1) != ")")
|
||||||
return;
|
member = false;
|
||||||
} else if (Token::Match(tok->tokAt(-2), ":|, %name%")) {
|
} else if (Token::Match(tok->tokAt(-2), ":|, %name%")) {
|
||||||
tok1 = tok1->tokAt(-2);
|
tok1 = tok1->tokAt(-2);
|
||||||
if (tok1->strAt(-1) != ")")
|
if (tok1->strAt(-1) != ")")
|
||||||
return;
|
member = false;
|
||||||
}
|
}
|
||||||
|
if (member) {
|
||||||
if (tok1->strAt(-1) == ">")
|
if (tok1->strAt(-1) == ">")
|
||||||
tok1 = tok1->previous()->findOpeningBracket();
|
tok1 = tok1->previous()->findOpeningBracket();
|
||||||
if (tok1 && Token::Match(tok1->tokAt(-3), "%name% :: %name%")) {
|
if (tok1 && Token::Match(tok1->tokAt(-3), "%name% :: %name%")) {
|
||||||
|
@ -2912,19 +2902,23 @@ void Tokenizer::calculateScopes()
|
||||||
tok1 = tok1->tokAt(-2);
|
tok1 = tok1->tokAt(-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nextScopeNameAddition.empty() && !scope.empty()) nextScopeNameAddition += " :: ";
|
if (!nextScopeNameAddition.empty() && !scope.empty())
|
||||||
|
nextScopeNameAddition += " :: ";
|
||||||
nextScopeNameAddition += scope;
|
nextScopeNameAddition += scope;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// New scope is opening, record it here
|
// New scope is opening, record it here
|
||||||
std::shared_ptr<ScopeInfo2> newScopeInfo = std::make_shared<ScopeInfo2>(tok->scopeInfo()->name, tok->link(), tok->scopeInfo()->usingNamespaces);
|
std::shared_ptr<ScopeInfo2> newScopeInfo = std::make_shared<ScopeInfo2>(tok->scopeInfo()->name, tok->link(), tok->scopeInfo()->usingNamespaces);
|
||||||
|
|
||||||
if (newScopeInfo->name != "" && nextScopeNameAddition != "") newScopeInfo->name.append(" :: ");
|
if (newScopeInfo->name != "" && nextScopeNameAddition != "")
|
||||||
|
newScopeInfo->name.append(" :: ");
|
||||||
newScopeInfo->name.append(nextScopeNameAddition);
|
newScopeInfo->name.append(nextScopeNameAddition);
|
||||||
nextScopeNameAddition = "";
|
nextScopeNameAddition = "";
|
||||||
|
|
||||||
if (tok->link()) tok->link()->scopeInfo(tok->scopeInfo());
|
if (tok->link())
|
||||||
|
tok->link()->scopeInfo(tok->scopeInfo());
|
||||||
tok->scopeInfo(newScopeInfo);
|
tok->scopeInfo(newScopeInfo);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -169,6 +169,7 @@ private:
|
||||||
TEST_CASE(template129);
|
TEST_CASE(template129);
|
||||||
TEST_CASE(template130); // #9246
|
TEST_CASE(template130); // #9246
|
||||||
TEST_CASE(template131); // #9249
|
TEST_CASE(template131); // #9249
|
||||||
|
TEST_CASE(template132); // #9250
|
||||||
TEST_CASE(template_specialization_1); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
TEST_CASE(template_specialization_1); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
||||||
TEST_CASE(template_specialization_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
TEST_CASE(template_specialization_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
||||||
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
|
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
|
||||||
|
@ -3129,6 +3130,33 @@ private:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void template132() { // #9250
|
||||||
|
const char code[] = "struct TrueFalse {\n"
|
||||||
|
" static constexpr bool v() { return true; }\n"
|
||||||
|
"};\n"
|
||||||
|
"int global;\n"
|
||||||
|
"template<typename T> int foo() {\n"
|
||||||
|
" __transaction_atomic noexcept(T::v()) { global += 1; }\n"
|
||||||
|
" return __transaction_atomic noexcept(T::v()) (global + 2);\n"
|
||||||
|
"}\n"
|
||||||
|
"int f1() {\n"
|
||||||
|
" return foo<TrueFalse>();\n"
|
||||||
|
"}";
|
||||||
|
const char exp[] = "struct TrueFalse { "
|
||||||
|
"static const bool v ( ) { return true ; } "
|
||||||
|
"} ; "
|
||||||
|
"int global ; "
|
||||||
|
"int foo<TrueFalse> ( ) ; "
|
||||||
|
"int f1 ( ) { "
|
||||||
|
"return foo<TrueFalse> ( ) ; "
|
||||||
|
"} "
|
||||||
|
"int foo<TrueFalse> ( ) { "
|
||||||
|
"__transaction_atomic noexcept ( TrueFalse :: v ( ) ) { global += 1 ; } "
|
||||||
|
"return __transaction_atomic noexcept ( TrueFalse :: v ( ) ) ( global + 2 ) ; "
|
||||||
|
"}";
|
||||||
|
ASSERT_EQUALS(exp, tok(code));
|
||||||
|
}
|
||||||
|
|
||||||
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
|
||||||
const char code[] = "template <typename T> struct C {};\n"
|
const char code[] = "template <typename T> struct C {};\n"
|
||||||
"template <typename T> struct S {a};\n"
|
"template <typename T> struct S {a};\n"
|
||||||
|
|
Loading…
Reference in New Issue