Ticket #7916: Don't incorrectly simplify return statements involving template instantiations.
This commit is contained in:
parent
774a8979a3
commit
487f76cdd1
|
@ -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);
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue