TemplateSimplifier: updated output of uninstantiated c++17 fold expressions

This commit is contained in:
Daniel Marjamäki 2021-04-21 13:13:11 +02:00
parent 35c934c887
commit bfb98dbf51
2 changed files with 33 additions and 10 deletions

View File

@ -3864,13 +3864,36 @@ void TemplateSimplifier::simplifyTemplates(
simplify = true;
if (!simplify || tok->str() != "(")
continue;
if (Token::Match(tok, "( ... %op%") ||
Token::Match(tok, "( %name% %op% ...") ||
Token::Match(tok->link()->tokAt(-3), "%op% ... )") ||
Token::Match(tok->link()->tokAt(-3), "... %op% %name% )")) {
Token::eraseTokens(tok, tok->link());
tok->insertToken("__cppcheck_uninstantiated_fold__");
const Token *op = nullptr;
const Token *args = nullptr;
if (Token::Match(tok, "( ... %op%")) {
op = tok->tokAt(2);
args = tok->link()->previous();
} else if (Token::Match(tok, "( %name% %op% ...")) {
op = tok->tokAt(2);
args = tok->link()->previous()->isName() ? nullptr : tok->next();
} else if (Token::Match(tok->link()->tokAt(-3), "%op% ... )")) {
op = tok->link()->tokAt(-2);
args = tok->next();
} else if (Token::Match(tok->link()->tokAt(-3), "... %op% %name% )")) {
op = tok->link()->tokAt(-2);
args = tok->next()->isName() ? nullptr : tok->link()->previous();
} else {
continue;
}
const std::string strop = op->str();
const std::string strargs = (args && args->isName()) ? args->str() : "";
Token::eraseTokens(tok, tok->link());
tok->insertToken(")");
if (!strargs.empty()) {
tok->insertToken("...");
tok->insertToken(strargs);
}
tok->insertToken("(");
Token::createMutualLinks(tok->next(), tok->link()->previous());
tok->insertToken("__cppcheck_fold_" + strop + "__");
}
}
}

View File

@ -6067,28 +6067,28 @@ private:
void fold_expression_1() {
const char code[] = "template<typename... Args> bool all(Args... args) { return (... && args); }\n"
"x=all(true,false,true,true);";
const char expected[] = "template < typename ... Args > bool all ( Args ... args ) { return ( __cppcheck_uninstantiated_fold__ ) ; } x = all ( true , false , true , true ) ;";
const char expected[] = "template < typename ... Args > bool all ( Args ... args ) { return ( __cppcheck_fold_&&__ ( args ... ) ) ; } x = all ( true , false , true , true ) ;";
ASSERT_EQUALS(expected, tok(code));
}
void fold_expression_2() {
const char code[] = "template<typename... Args> bool all(Args... args) { return (args && ...); }\n"
"x=all(true,false,true,true);";
const char expected[] = "template < typename ... Args > bool all ( Args ... args ) { return ( __cppcheck_uninstantiated_fold__ ) ; } x = all ( true , false , true , true ) ;";
const char expected[] = "template < typename ... Args > bool all ( Args ... args ) { return ( __cppcheck_fold_&&__ ( args ... ) ) ; } x = all ( true , false , true , true ) ;";
ASSERT_EQUALS(expected, tok(code));
}
void fold_expression_3() {
const char code[] = "template<typename... Args> int foo(Args... args) { return (12 * ... * args); }\n"
"x=foo(1,2);";
const char expected[] = "template < typename ... Args > int foo ( Args ... args ) { return ( __cppcheck_uninstantiated_fold__ ) ; } x = foo ( 1 , 2 ) ;";
const char expected[] = "template < typename ... Args > int foo ( Args ... args ) { return ( __cppcheck_fold_*__ ( args ... ) ) ; } x = foo ( 1 , 2 ) ;";
ASSERT_EQUALS(expected, tok(code));
}
void fold_expression_4() {
const char code[] = "template<typename... Args> int foo(Args... args) { return (args * ... * 123); }\n"
"x=foo(1,2);";
const char expected[] = "template < typename ... Args > int foo ( Args ... args ) { return ( __cppcheck_uninstantiated_fold__ ) ; } x = foo ( 1 , 2 ) ;";
const char expected[] = "template < typename ... Args > int foo ( Args ... args ) { return ( __cppcheck_fold_*__ ( args ... ) ) ; } x = foo ( 1 , 2 ) ;";
ASSERT_EQUALS(expected, tok(code));
}