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:
parent
ba037837c9
commit
4e222afa2c
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
Loading…
Reference in New Issue