Visitar URL original
Ticket #6567: Handle member functions in TemplateSimplifier::getTempl… · ProgramMax/cppcheck@1d973b8 · GitHub
Skip to content

Commit 1d973b8

Browse files
committed
Ticket cppcheck-opensource#6567: Handle member functions in TemplateSimplifier::getTemplateNamePosition.
1 parent 0131bda commit 1d973b8

2 files changed

Lines changed: 48 additions & 3 deletions

File tree

‎lib/templatesimplifier.cpp‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -699,18 +699,24 @@ bool TemplateSimplifier::instantiateMatch(const Token *instance, const std::stri
699699
int TemplateSimplifier::getTemplateNamePosition(const Token *tok)
700700
{
701701
// get the position of the template name
702-
int namepos = 0;
702+
int namepos = 0, starAmpPossiblePosition = 0;
703703
if (Token::Match(tok, "> class|struct %type% {|:"))
704704
namepos = 2;
705705
else if (Token::Match(tok, "> %type% *|&| %type% ("))
706706
namepos = 2;
707707
else if (Token::Match(tok, "> %type% %type% *|&| %type% ("))
708708
namepos = 3;
709-
else {
709+
else if (Token::Match(tok, "> %type% *|&| %type% :: %type% (")) {
710+
namepos = 4;
711+
starAmpPossiblePosition = 2;
712+
} else if (Token::Match(tok, "> %type% %type% *|&| %type% :: %type% (")) {
713+
namepos = 5;
714+
starAmpPossiblePosition = 3;
715+
} else {
710716
// Name not found
711717
return -1;
712718
}
713-
if ((tok->strAt(namepos) == "*" || tok->strAt(namepos) == "&"))
719+
if (Token::Match(tok->tokAt(starAmpPossiblePosition ? starAmpPossiblePosition : namepos), "*|&"))
714720
++namepos;
715721

716722
return namepos;

‎test/testsimplifytemplate.cpp‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ class TestSimplifyTemplate : public TestFixture {
9595
// Test TemplateSimplifier::templateParameters
9696
TEST_CASE(templateParameters);
9797
TEST_CASE(templateParameters1); // #4169 - segmentation fault
98+
99+
TEST_CASE(templateNamePosition);
98100
}
99101

100102
std::string tok(const char code[], bool simplify = true, Settings::PlatformType type = Settings::Unspecified) {
@@ -1110,6 +1112,43 @@ class TestSimplifyTemplate : public TestFixture {
11101112
// do not crash on invalid code
11111113
ASSERT_EQUALS(0, templateParameters(code));
11121114
}
1115+
1116+
// Helper function to unit test TemplateSimplifier::getTemplateNamePosition
1117+
int templateNamePositionHelper(const char code[], unsigned offset = 0) {
1118+
Settings settings;
1119+
Tokenizer tokenizer(&settings, this);
1120+
1121+
std::istringstream istr(code);
1122+
tokenizer.tokenize(istr, "test.cpp", "", true);
1123+
1124+
const Token *tok = tokenizer.tokens();
1125+
for (unsigned i = 0 ; i < offset ; ++i)
1126+
tok = tok->next();
1127+
return TemplateSimplifier::getTemplateNamePosition(tok);
1128+
}
1129+
1130+
void templateNamePosition() {
1131+
// Template class
1132+
ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> class A {};", 4));
1133+
ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> struct A {};", 4));
1134+
ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> class A : B {};", 4));
1135+
ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> struct A : B {};", 4));
1136+
// Template function definitions
1137+
ASSERT_EQUALS(2, templateNamePositionHelper("template<class T> unsigned foo() { return 0; }", 4));
1138+
ASSERT_EQUALS(3, templateNamePositionHelper("template<class T> unsigned* foo() { return 0; }", 4));
1139+
ASSERT_EQUALS(3, templateNamePositionHelper("template<class T> const unsigned foo() { return 0; }", 4));
1140+
ASSERT_EQUALS(4, templateNamePositionHelper("template<class T> const unsigned& foo() { return 0; }", 4));
1141+
// Class template members
1142+
ASSERT_EQUALS(4, templateNamePositionHelper("class A { template<class T> unsigned foo(); }; "
1143+
"template<class T> unsigned A::foo() { return 0; }", 19));
1144+
ASSERT_EQUALS(5, templateNamePositionHelper("class A { template<class T> const unsigned foo(); }; "
1145+
"template<class T> const unsigned A::foo() { return 0; }", 20));
1146+
TODO_ASSERT_EQUALS(7, -1, templateNamePositionHelper("class A { class B { template<class T> const unsigned foo(); }; } ; "
1147+
"template<class T> const unsigned A::B::foo() { return 0; }", 25));
1148+
// Template class member
1149+
TODO_ASSERT_EQUALS(7, -1, templateNamePositionHelper("template<class T> class A { unsigned foo(); }; "
1150+
"template<class T> unsigned A<T>::foo() { return 0; }", 19));
1151+
}
11131152
};
11141153

11151154
REGISTER_TEST(TestSimplifyTemplate)

0 commit comments

Comments
 (0)