Ticket #8175: Fix bug in TemplateSimplifier::instantiateMatch with template parameters involving sizeof or namespace.

This commit is contained in:
Simon Martin 2017-12-02 19:18:36 +01:00
parent fd76abba16
commit 1b14380007
2 changed files with 29 additions and 1 deletions

View File

@ -695,7 +695,7 @@ bool TemplateSimplifier::instantiateMatch(const Token *instance, const std::stri
const Token *tok = instance; const Token *tok = instance;
unsigned int indentlevel = 0; unsigned int indentlevel = 0;
for (tok = instance; tok && (tok->str() != ">" || indentlevel > 0); tok = tok->next()) { for (tok = instance; tok && (tok->str() != ">" || indentlevel > 0); tok = tok->next()) {
if (Token::Match(tok, "[<,] %name% <") && templateParameters(tok->tokAt(2)) > 0) if (Token::Match(tok, "<|,|(|:: %name% <") && templateParameters(tok->tokAt(2)) > 0)
++indentlevel; ++indentlevel;
if (indentlevel > 0 && tok->str() == ">") if (indentlevel > 0 && tok->str() == ">")
--indentlevel; --indentlevel;

View File

@ -113,6 +113,9 @@ private:
TEST_CASE(templateNamePosition); TEST_CASE(templateNamePosition);
TEST_CASE(expandSpecialized); TEST_CASE(expandSpecialized);
// Test TemplateSimplifier::instantiateMatch
TEST_CASE(instantiateMatch);
} }
std::string tok(const char code[], bool simplify = true, bool debugwarnings = false, Settings::PlatformType type = Settings::Native) { std::string tok(const char code[], bool simplify = true, bool debugwarnings = false, Settings::PlatformType type = Settings::Native) {
@ -1473,6 +1476,31 @@ private:
ASSERT_EQUALS("class A < int > { } ;", tok("template<> class A<int> {};")); ASSERT_EQUALS("class A < int > { } ;", tok("template<> class A<int> {};"));
ASSERT_EQUALS("class A < int > : public B { } ;", tok("template<> class A<int> : public B {};")); ASSERT_EQUALS("class A < int > : public B { } ;", tok("template<> class A<int> : public B {};"));
} }
unsigned int instantiateMatch(const char code[], const std::string& name, const std::size_t numberOfArguments, const char patternAfter[]) {
Tokenizer tokenizer(&settings, this);
std::istringstream istr(code);
tokenizer.tokenize(istr, "test.cpp", "");
return TemplateSimplifier::instantiateMatch(tokenizer.tokens(), name, numberOfArguments, patternAfter);
}
void instantiateMatch() {
// Ticket #8175
ASSERT_EQUALS(false,
instantiateMatch("ConvertHelper < From, To > c ;",
"ConvertHelper", 2, ":: %name% ("));
ASSERT_EQUALS(true,
instantiateMatch("ConvertHelper < From, To > :: Create ( ) ;",
"ConvertHelper", 2, ":: %name% ("));
ASSERT_EQUALS(false,
instantiateMatch("integral_constant < bool, sizeof ( ConvertHelper < From, To > :: Create ( ) ) > ;",
"integral_constant", 2, ":: %name% ("));
ASSERT_EQUALS(false,
instantiateMatch("integral_constant < bool, sizeof ( ns :: ConvertHelper < From, To > :: Create ( ) ) > ;",
"integral_constant", 2, ":: %name% ("));
}
}; };
REGISTER_TEST(TestSimplifyTemplate) REGISTER_TEST(TestSimplifyTemplate)