From 4e222afa2c875c9290109b97a97f6f1330837165 Mon Sep 17 00:00:00 2001 From: IOBYTE Date: Wed, 11 Sep 2019 13:31:15 -0400 Subject: [PATCH] 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 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. --- lib/templatesimplifier.cpp | 8 +++++--- test/testsimplifytemplate.cpp | 23 +++++++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/lib/templatesimplifier.cpp b/lib/templatesimplifier.cpp index 6c5ad41d5..138ddea73 100644 --- a/lib/templatesimplifier.cpp +++ b/lib/templatesimplifier.cpp @@ -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 diff --git a/test/testsimplifytemplate.cpp b/test/testsimplifytemplate.cpp index dca36f880..215412f65 100644 --- a/test/testsimplifytemplate.cpp +++ b/test/testsimplifytemplate.cpp @@ -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 struct S> {..}; TEST_CASE(template_specialization_2); // #7868 - template specialization template struct S> {..}; 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\n" + "using A1 = struct B1 { static auto constexpr value = N; };\n" + "A1<0> a1;\n" + "template\n" + "using A2 = struct B2 { void f(T){} };\n" + "A2 a2;\n" + "template\n" + "using A3 = enum B3 {b = 0;};\n" + "A3 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 struct S> {..}; const char code[] = "template struct C {};\n" "template struct S {a};\n"