Skip to content

Commit

Permalink
fix template simplifier overloaded specialized instantiations (danmar…
Browse files Browse the repository at this point in the history
  • Loading branch information
IOBYTE authored Feb 28, 2021
1 parent c9bc5a0 commit 8c57e2b
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 7 deletions.
24 changes: 17 additions & 7 deletions lib/templatesimplifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2858,7 +2858,10 @@ bool TemplateSimplifier::matchSpecialization(
if (!endToken)
continue;
while (declToken != endToken) {
if (declToken->str() != instToken->str()) {
if (declToken->str() != instToken->str() ||
declToken->isSigned() != instToken->isSigned() ||
declToken->isUnsigned() != instToken->isUnsigned() ||
declToken->isLong() != instToken->isLong()) {
int nr = 0;
while (nr < templateParameters.size() && templateParameters[nr]->str() != declToken->str())
++nr;
Expand Down Expand Up @@ -2915,14 +2918,15 @@ std::string TemplateSimplifier::getNewName(
}
// add additional type information
if (!constconst && !Token::Match(tok3, "class|struct|enum")) {
if (tok3->isUnsigned())
typeForNewName += "unsigned";
else if (tok3->isSigned())
typeForNewName += "signed";
if (tok3->isLong())
typeForNewName += "long";
if (!typeForNewName.empty())
typeForNewName += ' ';
if (tok3->isUnsigned())
typeForNewName += "unsigned ";
else if (tok3->isSigned())
typeForNewName += "signed ";
if (tok3->isLong()) {
typeForNewName += "long ";
}
typeForNewName += tok3->str();
}
}
Expand Down Expand Up @@ -3467,6 +3471,12 @@ void TemplateSimplifier::printOut(const TokenAndName &tokenAndName, const std::s
const Token *start = tokenAndName.token()->next();
std::cout << indent << "type: ";
while (start && start != end) {
if (start->isUnsigned())
std::cout << "unsigned";
else if (start->isSigned())
std::cout << "signed";
if (start->isLong())
std::cout << "long";
std::cout << start->str();
start = start->next();
}
Expand Down
46 changes: 46 additions & 0 deletions test/testsimplifytemplate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,7 @@ class TestSimplifyTemplate : public TestFixture {
TEST_CASE(template165); // #10032 syntax error
TEST_CASE(template166); // #10081 hang
TEST_CASE(template167);
TEST_CASE(template168);
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_enum); // #6299 Syntax error in complex enum declaration (including template)
Expand Down Expand Up @@ -4218,6 +4219,51 @@ class TestSimplifyTemplate : public TestFixture {
ASSERT_EQUALS(exp, tok(code));
}

void template168() {
const char code[] = "template < typename T, typename U > struct type { };\n"
"template < > struct type < bool, bool > {};\n"
"template < > struct type < unsigned char, unsigned char > {};\n"
"template < > struct type < char, char > {};\n"
"template < > struct type < signed char, signed char > {};\n"
"template < > struct type < unsigned short, unsigned short > {};\n"
"template < > struct type < short, short > {};\n"
"template < > struct type < unsigned int, unsigned int > {};\n"
"template < > struct type < int, int > {};\n"
"template < > struct type < unsigned long long, unsigned long long > {};\n"
"template < > struct type < long long, long long > {};\n"
"template < > struct type < double, double > {};\n"
"template < > struct type < float, float > {};\n"
"template < > struct type < long double, long double > {};";
const char exp[] = "struct type<longdouble,longdouble> ; "
"struct type<float,float> ; "
"struct type<double,double> ; "
"struct type<longlong,longlong> ; "
"struct type<unsignedlonglong,unsignedlonglong> ; "
"struct type<int,int> ; "
"struct type<unsignedint,unsignedint> ; "
"struct type<short,short> ; "
"struct type<unsignedshort,unsignedshort> ; "
"struct type<signedchar,signedchar> ; "
"struct type<char,char> ; "
"struct type<unsignedchar,unsignedchar> ; "
"struct type<bool,bool> ; "
"template < typename T , typename U > struct type { } ; "
"struct type<bool,bool> { } ; "
"struct type<unsignedchar,unsignedchar> { } ; "
"struct type<char,char> { } ; "
"struct type<signedchar,signedchar> { } ; "
"struct type<unsignedshort,unsignedshort> { } ; "
"struct type<short,short> { } ; "
"struct type<unsignedint,unsignedint> { } ; "
"struct type<int,int> { } ; "
"struct type<unsignedlonglong,unsignedlonglong> { } ; "
"struct type<longlong,longlong> { } ; "
"struct type<double,double> { } ; "
"struct type<float,float> { } ; "
"struct type<longdouble,longdouble> { } ;";
ASSERT_EQUALS(exp, tok(code));
}

void template_specialization_1() { // #7868 - template specialization template <typename T> struct S<C<T>> {..};
const char code[] = "template <typename T> struct C {};\n"
"template <typename T> struct S {a};\n"
Expand Down

0 comments on commit 8c57e2b

Please sign in to comment.