fix template simplifier overloaded specialized instantiations (#3154)

This commit is contained in:
IOBYTE 2021-02-28 15:52:14 -05:00 committed by GitHub
parent c9bc5a076f
commit 8c57e2bb14
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 63 additions and 7 deletions

View File

@ -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;
@ -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();
}
}
@ -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();
}

View File

@ -210,6 +210,7 @@ private:
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)
@ -4218,6 +4219,51 @@ private:
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"