fix #9394 ("debug: Executable scope 'x' with unknown function." with … (#2935)

This commit is contained in:
IOBYTE 2020-12-06 16:08:42 -05:00 committed by GitHub
parent e541d01533
commit 8d9f0b3528
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 67 additions and 5 deletions

View File

@ -151,8 +151,12 @@ TemplateSimplifier::TokenAndName::TokenAndName(Token *token, const std::string &
}
}
// check for member class or function and adjust scope
if ((isFunction() || isClass()) && mNameToken->strAt(-1) == "::") {
if ((isFunction() || isClass()) &&
(mNameToken->strAt(-1) == "::" || Token::simpleMatch(mNameToken->tokAt(-2), ":: ~"))) {
const Token * start = mNameToken;
if (start->strAt(-1) == "~")
start = start->previous();
const Token *end = start;
while (start && (Token::Match(start->tokAt(-2), "%name% ::") ||
(Token::simpleMatch(start->tokAt(-2), "> ::") &&
@ -164,10 +168,10 @@ TemplateSimplifier::TokenAndName::TokenAndName(Token *token, const std::string &
start = start->tokAt(-2);
}
if (start && start != nameToken) {
if (start && start != end) {
if (!mScope.empty())
mScope += " ::";
while (start && start->next() != mNameToken) {
while (start && start->next() != end) {
if (start->str() == "<")
start = start->findClosingBracket();
else {
@ -3024,6 +3028,17 @@ bool TemplateSimplifier::simplifyTemplateInstantiations(
continue;
}
// make sure constructors and destructors don't match each other
if (templateDeclaration.nameToken()->strAt(-1) == "~" && instantiation.token()->strAt(-1) != "~")
continue;
// template families should match
if (!instantiation.isFunction() && templateDeclaration.isFunction()) {
// there are exceptions
if (!Token::simpleMatch(instantiation.token()->tokAt(-2), "decltype ("))
continue;
}
if (templateDeclaration.isFunction() && instantiation.isFunction()) {
std::vector<const Token*> declFuncArgs;
getFunctionArguments(templateDeclaration.nameToken(), declFuncArgs);

View File

@ -206,6 +206,7 @@ private:
TEST_CASE(template161);
TEST_CASE(template162);
TEST_CASE(template163); // #9685 syntax error
TEST_CASE(template164); // #9394
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)
@ -4096,14 +4097,24 @@ private:
void template162() {
const char code[] = "template <std::size_t N>\n"
"struct CountryCode {\n"
" CountryCode(std::string cc);\n"
"};"
"template <std::size_t N>\n"
"CountryCode<N>::CountryCode(std::string cc) : m_String{std::move(cc)} {\n"
"}\n"
"template class CountryCode<2>;\n"
"template class CountryCode<3>;";
const char exp[] = "CountryCode<2> :: CountryCode<2> ( std :: string cc ) ; "
"CountryCode<3> :: CountryCode<3> ( std :: string cc ) ; "
const char exp[] = "struct CountryCode<2> ; "
"struct CountryCode<3> ; "
"struct CountryCode<2> { "
"CountryCode<2> ( std :: string cc ) ; "
"} ; "
"CountryCode<2> :: CountryCode<2> ( std :: string cc ) : m_String { std :: move ( cc ) } { "
"} "
"struct CountryCode<3> { "
"CountryCode<3> ( std :: string cc ) ; "
"} ; "
"CountryCode<3> :: CountryCode<3> ( std :: string cc ) : m_String { std :: move ( cc ) } { "
"}";
ASSERT_EQUALS(exp, tok(code));
@ -4114,6 +4125,42 @@ private:
ASSERT_EQUALS(code, tok(code));
}
void template164() { // #9394
const char code[] = "template <class TYPE>\n"
"struct A {\n"
" A();\n"
" ~A();\n"
" static void f();\n"
"};\n"
"template <class TYPE>\n"
"A<TYPE>::A() { }\n"
"template <class TYPE>\n"
"A<TYPE>::~A() { }\n"
"template <class TYPE>\n"
"void A<TYPE>::f() { }\n"
"template class A<int>;\n"
"template class A<float>;";
const char exp[] = "struct A<int> ; "
"struct A<float> ; "
"struct A<int> { "
"A<int> ( ) ; "
"~ A<int> ( ) ; "
"static void f ( ) ; "
"} ; "
"A<int> :: A<int> ( ) { } "
"A<int> :: ~ A<int> ( ) { } "
"void A<int> :: f ( ) { } "
"struct A<float> { "
"A<float> ( ) ; "
"~ A<float> ( ) ; "
"static void f ( ) ; "
"} ; "
"A<float> :: A<float> ( ) { } "
"A<float> :: ~ A<float> ( ) { } "
"void A<float> :: f ( ) { }";
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"