This fixes simplifyUsing to remove 'typename' and 'template' from type aliases of the form: using T3 = typename T1::template T3<T2>; This lets the template simplifier instantiate the type alias which will then remove the using type alias. The crash will still happen if there is no instantiation because the type alias will not be removed. The type alias is what cppcheck is crashing on after the template simplifier and that still needs fixing.
This commit is contained in:
parent
ff8cf4fe25
commit
e786c6b7d4
|
@ -3021,9 +3021,9 @@ void TemplateSimplifier::simplifyTemplates(
|
|||
const std::time_t maxtime,
|
||||
bool &codeWithTemplates)
|
||||
{
|
||||
// Remove "typename" unless used in template arguments..
|
||||
// Remove "typename" unless used in template arguments or using type alias..
|
||||
for (Token *tok = mTokenList.front(); tok; tok = tok->next()) {
|
||||
if (Token::Match(tok, "typename %name%"))
|
||||
if (Token::Match(tok, "typename %name%") && !Token::Match(tok->tokAt(-3), "using %name% ="))
|
||||
tok->deleteThis();
|
||||
|
||||
if (Token::simpleMatch(tok, "template <")) {
|
||||
|
|
|
@ -1797,7 +1797,7 @@ namespace {
|
|||
return false;
|
||||
}
|
||||
|
||||
if (Token::Match(tok1->tokAt(-1), "struct|union|enum")) {
|
||||
if (Token::Match(tok1->tokAt(-1), "class|struct|union|enum")) {
|
||||
// fixme
|
||||
return false;
|
||||
}
|
||||
|
@ -1977,6 +1977,16 @@ bool Tokenizer::simplifyUsing()
|
|||
}
|
||||
}
|
||||
|
||||
// remove 'typename' and 'template'
|
||||
else if (start->str() == "typename") {
|
||||
start->deleteThis();
|
||||
Token *temp = start;
|
||||
while (Token::Match(temp, "%name% ::"))
|
||||
temp = temp->tokAt(2);
|
||||
if (Token::Match(temp, "template %name%"))
|
||||
temp->deleteThis();
|
||||
}
|
||||
|
||||
// Unfortunately we have to start searching from the beginning
|
||||
// of the token stream because templates are instantiated at
|
||||
// the end of the token stream and it may be used before then.
|
||||
|
|
|
@ -144,6 +144,7 @@ private:
|
|||
TEST_CASE(template104); // #9021
|
||||
TEST_CASE(template105); // #9076
|
||||
TEST_CASE(template106);
|
||||
TEST_CASE(template107); // #8663
|
||||
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)
|
||||
|
@ -2420,6 +2421,34 @@ private:
|
|||
ASSERT_EQUALS(exp, tok(code));
|
||||
}
|
||||
|
||||
void template107() { // #8663
|
||||
const char code[] = "template <class T1, class T2>\n"
|
||||
"void f() {\n"
|
||||
" using T3 = typename T1::template T3<T2>;\n"
|
||||
" T3 t;\n"
|
||||
"}\n"
|
||||
"struct C3 {\n"
|
||||
" template <typename T>\n"
|
||||
" class T3\n"
|
||||
" {};\n"
|
||||
"};\n"
|
||||
"void foo() {\n"
|
||||
" f<C3, long>();\n"
|
||||
"}";
|
||||
const char exp[] = "void f<C3,long> ( ) ; "
|
||||
"struct C3 { "
|
||||
"class T3<long> ; "
|
||||
"} ; "
|
||||
"void foo ( ) { "
|
||||
"f<C3,long> ( ) ; "
|
||||
"} "
|
||||
"void f<C3,long> ( ) { "
|
||||
"C3 :: T3<long> t ; "
|
||||
"} "
|
||||
"class C3 :: T3<long> { } ;";
|
||||
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"
|
||||
|
|
Loading…
Reference in New Issue