Ticket #7916: Don't incorrectly simplify return statements involving template instantiations.

This commit is contained in:
Simon Martin 2017-02-18 21:14:50 +01:00
parent 774a8979a3
commit 487f76cdd1
2 changed files with 28 additions and 0 deletions

View File

@ -5300,6 +5300,10 @@ bool Tokenizer::simplifyFunctionReturn()
const std::string pattern("(|[|=|return|%op% " + tok->str() + " ( ) ;|]|)|%cop%");
for (Token *tok2 = list.front(); tok2; tok2 = tok2->next()) {
if (Token::Match(tok2, pattern.c_str())) {
if (tok->str() != tok2->strAt(1))
// Ticket #7916: tok is for instance "foo < bar >", a single token for an instantiation,
// and tok2->strAt(1) is "foo"; bail out (TODO: we can probably handle this pattern)
continue;
tok2 = tok2->next();
tok2->str(any->str());
tok2->deleteNext(2);

View File

@ -3322,6 +3322,30 @@ private:
"const std :: string & Fred :: foo ( ) { return \"\" ; }";
ASSERT_EQUALS(expected, tok(code, false));
}
{
// Ticket #7916
// Tokenization would include "int fact < 2 > ( ) { return 2 > ( ) ; }" and generate
// a parse error (and use after free)
const char code[] = "extern \"C\" void abort ();\n"
"template <int a> inline int fact2 ();\n"
"template <int a> inline int fact () {\n"
" return a * fact2<a-1> ();\n"
"}\n"
"template <> inline int fact<1> () {\n"
" return 1;\n"
"}\n"
"template <int a> inline int fact2 () {\n"
" return a * fact<a-1>();\n"
"}\n"
"template <> inline int fact2<1> () {\n"
" return 1;\n"
"}\n"
"int main() {\n"
" fact2<3> ();\n"
" fact2<2> ();\n"
"}";
tok(code);
}
}
void removeVoidFromFunction() {