Skip to content

Commit 8c57e2b

Browse files
authored
fix template simplifier overloaded specialized instantiations (danmar#3154)
1 parent c9bc5a0 commit 8c57e2b

File tree

2 files changed

+63
-7
lines changed

2 files changed

+63
-7
lines changed

lib/templatesimplifier.cpp

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2858,7 +2858,10 @@ bool TemplateSimplifier::matchSpecialization(
28582858
if (!endToken)
28592859
continue;
28602860
while (declToken != endToken) {
2861-
if (declToken->str() != instToken->str()) {
2861+
if (declToken->str() != instToken->str() ||
2862+
declToken->isSigned() != instToken->isSigned() ||
2863+
declToken->isUnsigned() != instToken->isUnsigned() ||
2864+
declToken->isLong() != instToken->isLong()) {
28622865
int nr = 0;
28632866
while (nr < templateParameters.size() && templateParameters[nr]->str() != declToken->str())
28642867
++nr;
@@ -2915,14 +2918,15 @@ std::string TemplateSimplifier::getNewName(
29152918
}
29162919
// add additional type information
29172920
if (!constconst && !Token::Match(tok3, "class|struct|enum")) {
2918-
if (tok3->isUnsigned())
2919-
typeForNewName += "unsigned";
2920-
else if (tok3->isSigned())
2921-
typeForNewName += "signed";
2922-
if (tok3->isLong())
2923-
typeForNewName += "long";
29242921
if (!typeForNewName.empty())
29252922
typeForNewName += ' ';
2923+
if (tok3->isUnsigned())
2924+
typeForNewName += "unsigned ";
2925+
else if (tok3->isSigned())
2926+
typeForNewName += "signed ";
2927+
if (tok3->isLong()) {
2928+
typeForNewName += "long ";
2929+
}
29262930
typeForNewName += tok3->str();
29272931
}
29282932
}
@@ -3467,6 +3471,12 @@ void TemplateSimplifier::printOut(const TokenAndName &tokenAndName, const std::s
34673471
const Token *start = tokenAndName.token()->next();
34683472
std::cout << indent << "type: ";
34693473
while (start && start != end) {
3474+
if (start->isUnsigned())
3475+
std::cout << "unsigned";
3476+
else if (start->isSigned())
3477+
std::cout << "signed";
3478+
if (start->isLong())
3479+
std::cout << "long";
34703480
std::cout << start->str();
34713481
start = start->next();
34723482
}

test/testsimplifytemplate.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,7 @@ class TestSimplifyTemplate : public TestFixture {
210210
TEST_CASE(template165); // #10032 syntax error
211211
TEST_CASE(template166); // #10081 hang
212212
TEST_CASE(template167);
213+
TEST_CASE(template168);
213214
TEST_CASE(template_specialization_1); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
214215
TEST_CASE(template_specialization_2); // #7868 - template specialization template <typename T> struct S<C<T>> {..};
215216
TEST_CASE(template_enum); // #6299 Syntax error in complex enum declaration (including template)
@@ -4218,6 +4219,51 @@ class TestSimplifyTemplate : public TestFixture {
42184219
ASSERT_EQUALS(exp, tok(code));
42194220
}
42204221

4222+
void template168() {
4223+
const char code[] = "template < typename T, typename U > struct type { };\n"
4224+
"template < > struct type < bool, bool > {};\n"
4225+
"template < > struct type < unsigned char, unsigned char > {};\n"
4226+
"template < > struct type < char, char > {};\n"
4227+
"template < > struct type < signed char, signed char > {};\n"
4228+
"template < > struct type < unsigned short, unsigned short > {};\n"
4229+
"template < > struct type < short, short > {};\n"
4230+
"template < > struct type < unsigned int, unsigned int > {};\n"
4231+
"template < > struct type < int, int > {};\n"
4232+
"template < > struct type < unsigned long long, unsigned long long > {};\n"
4233+
"template < > struct type < long long, long long > {};\n"
4234+
"template < > struct type < double, double > {};\n"
4235+
"template < > struct type < float, float > {};\n"
4236+
"template < > struct type < long double, long double > {};";
4237+
const char exp[] = "struct type<longdouble,longdouble> ; "
4238+
"struct type<float,float> ; "
4239+
"struct type<double,double> ; "
4240+
"struct type<longlong,longlong> ; "
4241+
"struct type<unsignedlonglong,unsignedlonglong> ; "
4242+
"struct type<int,int> ; "
4243+
"struct type<unsignedint,unsignedint> ; "
4244+
"struct type<short,short> ; "
4245+
"struct type<unsignedshort,unsignedshort> ; "
4246+
"struct type<signedchar,signedchar> ; "
4247+
"struct type<char,char> ; "
4248+
"struct type<unsignedchar,unsignedchar> ; "
4249+
"struct type<bool,bool> ; "
4250+
"template < typename T , typename U > struct type { } ; "
4251+
"struct type<bool,bool> { } ; "
4252+
"struct type<unsignedchar,unsignedchar> { } ; "
4253+
"struct type<char,char> { } ; "
4254+
"struct type<signedchar,signedchar> { } ; "
4255+
"struct type<unsignedshort,unsignedshort> { } ; "
4256+
"struct type<short,short> { } ; "
4257+
"struct type<unsignedint,unsignedint> { } ; "
4258+
"struct type<int,int> { } ; "
4259+
"struct type<unsignedlonglong,unsignedlonglong> { } ; "
4260+
"struct type<longlong,longlong> { } ; "
4261+
"struct type<double,double> { } ; "
4262+
"struct type<float,float> { } ; "
4263+
"struct type<longdouble,longdouble> { } ;";
4264+
ASSERT_EQUALS(exp, tok(code));
4265+
}
4266+
42214267
void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
42224268
const char code[] = "template <typename T> struct C {};\n"
42234269
"template <typename T> struct S {a};\n"

0 commit comments

Comments
 (0)