template simplifier: ignore alias template definitions with syntax errors (#2169)

Is not allowed to define a type in an alias template definition.

This code:

template<int N>
using A1 = struct B1 { static auto constexpr value = N; };
A1<0> a1;

produces this output:

2: } ;
3: struct B1 { static const auto value = 0 a1 ;

test.cpp:2:57: error: Analysis failed. If the code is valid then please
report this failure. [cppcheckError]
using A1 = struct B1 { static auto constexpr value = N; };
                                                        ^

because it tries to instantiate the invalid alias template definition
and generates garbage code.
This commit is contained in:
IOBYTE 2019-09-11 13:31:15 -04:00 committed by Daniel Marjamäki
parent ba037837c9
commit 4e222afa2c
2 changed files with 28 additions and 3 deletions

View File

@ -1441,9 +1441,11 @@ int TemplateSimplifier::getTemplateNamePosition(const Token *tok)
int namepos = 0;
if (getTemplateNamePositionTemplateClass(tok, namepos))
;
else if (Token::Match(tok, "> using %name% ="))
namepos = 2;
else if (getTemplateNamePositionTemplateVariable(tok, namepos))
else if (Token::Match(tok, "> using %name% =")) {
// types may not be defined in alias template declarations
if (!Token::Match(tok->tokAt(4), "class|struct|union|enum %name%| {"))
namepos = 2;
} else if (getTemplateNamePositionTemplateVariable(tok, namepos))
;
else if (!getTemplateNamePositionTemplateFunction(tok, namepos))
namepos = -1; // Name not found

View File

@ -180,6 +180,7 @@ private:
TEST_CASE(template140);
TEST_CASE(template141); // #9337
TEST_CASE(template142); // #9338
TEST_CASE(template143);
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)
@ -3456,6 +3457,28 @@ private:
ASSERT_EQUALS(exp, tok(code));
}
void template143() {
const char code[] = "template<int N>\n"
"using A1 = struct B1 { static auto constexpr value = N; };\n"
"A1<0> a1;\n"
"template<class T>\n"
"using A2 = struct B2 { void f(T){} };\n"
"A2<bool> a2;\n"
"template<class T>\n"
"using A3 = enum B3 {b = 0;};\n"
"A3<int> a3;";
const char exp[] = "template < int N > "
"using A1 = struct B1 { static const auto value = N ; } ; "
"A1 < 0 > a1 ; "
"template < class T > "
"using A2 = struct B2 { void f ( T ) { } } ; "
"A2 < bool > a2 ; "
"template < class T > "
"using A3 = enum B3 { b = 0 ; } ; "
"A3 < int > a3 ;";
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"