#6865 TemplateSimplifier::expandTemplate doesn't terminate on invalid code. Add some another syntax check on templates to avoid problems later on.
This commit is contained in:
parent
9bb2af1893
commit
21efa992e3
|
@ -471,6 +471,11 @@ std::list<Token *> TemplateSimplifier::getTemplateDeclarations(Token *tokens, bo
|
||||||
|
|
||||||
if (Token::simpleMatch(tok, "template <")) {
|
if (Token::simpleMatch(tok, "template <")) {
|
||||||
Token *parmEnd = tok->next()->findClosingBracket();
|
Token *parmEnd = tok->next()->findClosingBracket();
|
||||||
|
if (!tok->tokAt(2))
|
||||||
|
syntaxError(tok->next());
|
||||||
|
if (tok->tokAt(2)->str()=="typename" &&
|
||||||
|
(!tok->tokAt(3) || !Token::Match(tok->tokAt(3), "%name%|.")))
|
||||||
|
syntaxError(tok->next());
|
||||||
codeWithTemplates = true;
|
codeWithTemplates = true;
|
||||||
|
|
||||||
int indentlevel = 0;
|
int indentlevel = 0;
|
||||||
|
|
|
@ -192,6 +192,7 @@ private:
|
||||||
TEST_CASE(garbageCode141); // #7043
|
TEST_CASE(garbageCode141); // #7043
|
||||||
TEST_CASE(garbageCode142); // #7050
|
TEST_CASE(garbageCode142); // #7050
|
||||||
TEST_CASE(garbageCode143); // #6922
|
TEST_CASE(garbageCode143); // #6922
|
||||||
|
TEST_CASE(garbageCode144); // #6865
|
||||||
|
|
||||||
TEST_CASE(garbageValueFlow);
|
TEST_CASE(garbageValueFlow);
|
||||||
TEST_CASE(garbageSymbolDatabase);
|
TEST_CASE(garbageSymbolDatabase);
|
||||||
|
@ -917,7 +918,8 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode119() { // #5598
|
void garbageCode119() { // #5598
|
||||||
checkCode("{ { void foo() { struct }; template <typename> struct S { Used x; void bar() } auto f = [this] { }; } };");
|
ASSERT_THROW(checkCode("{ { void foo() { struct }; template <typename> struct S { Used x; void bar() } auto f = [this] { }; } };"),
|
||||||
|
InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
void garbageCode120() { // #4927
|
void garbageCode120() { // #4927
|
||||||
|
@ -1133,6 +1135,10 @@ private:
|
||||||
"}"), InternalError);
|
"}"), InternalError);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void garbageCode144() { // #6865
|
||||||
|
ASSERT_THROW(checkCode("template < typename > struct A { } ; template < typename > struct A < INVALID > : A < int[ > { }] ;"), InternalError);
|
||||||
|
}
|
||||||
|
|
||||||
void garbageValueFlow() {
|
void garbageValueFlow() {
|
||||||
// #6089
|
// #6089
|
||||||
const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"
|
const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"
|
||||||
|
@ -1217,24 +1223,24 @@ private:
|
||||||
|
|
||||||
checkCode(" > template < . > struct Y < T > { = } ;\n"); // #6108
|
checkCode(" > template < . > struct Y < T > { = } ;\n"); // #6108
|
||||||
|
|
||||||
checkCode( // #6117
|
ASSERT_THROW(checkCode( // #6117
|
||||||
"template <typename ...> struct something_like_tuple\n"
|
"template <typename ...> struct something_like_tuple\n"
|
||||||
"{};\n"
|
"{};\n"
|
||||||
"template <typename, typename> struct is_last {\n"
|
"template <typename, typename> struct is_last {\n"
|
||||||
" static const bool value = false;\n"
|
" static const bool value = false;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"template <typename T, template <typename ...> class Tuple, typename ... Head>\n"
|
"template <typename T, template <typename ...> class Tuple, typename ... Head>\n"
|
||||||
"struct is_last<T, Tuple<Head ..., T>>\n"
|
"struct is_last<T, Tuple<Head ..., T>>\n"
|
||||||
"{\n"
|
"{\n"
|
||||||
" static const bool value = true;\n"
|
" static const bool value = true;\n"
|
||||||
"};\n"
|
"};\n"
|
||||||
"\n"
|
"\n"
|
||||||
"#define SA(X) static_assert (X, #X)\n"
|
"#define SA(X) static_assert (X, #X)\n"
|
||||||
"\n"
|
"\n"
|
||||||
"typedef something_like_tuple<char, int, float> something_like_tuple_t;\n"
|
"typedef something_like_tuple<char, int, float> something_like_tuple_t;\n"
|
||||||
"SA ((is_last<float, something_like_tuple_t>::value == false));\n"
|
"SA ((is_last<float, something_like_tuple_t>::value == false));\n"
|
||||||
"SA ((is_last<int, something_like_tuple_t>::value == false));\n"
|
"SA ((is_last<int, something_like_tuple_t>::value == false));\n"
|
||||||
);
|
), InternalError);
|
||||||
|
|
||||||
checkCode( // #6225
|
checkCode( // #6225
|
||||||
"template <typename...>\n"
|
"template <typename...>\n"
|
||||||
|
|
|
@ -663,8 +663,7 @@ private:
|
||||||
}
|
}
|
||||||
|
|
||||||
void varid28() { // ticket #2630 (segmentation fault)
|
void varid28() { // ticket #2630 (segmentation fault)
|
||||||
tokenize("template <typedef A>\n");
|
ASSERT_THROW(tokenize("template <typedef A>\n"), InternalError);
|
||||||
ASSERT_EQUALS("", errout.str());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void varid29() {
|
void varid29() {
|
||||||
|
|
Loading…
Reference in New Issue