fix #8965 ("(debug) Executable scope 'x' with unknown function." with rvalue parameter in method) (#2237)

I fixed the AST enough to pass testrunner but I don't believe it is
correct.

This code:

void Foo4(int&&b);

has this AST:

( 'void'
|-Foo4
`-&& 'bool'
  |-int
  `-b 'signed int'

but I don't believe && should have `bool`.
This commit is contained in:
IOBYTE 2019-10-04 06:30:11 -04:00 committed by Daniel Marjamäki
parent 2a33c3cfec
commit c32a568c1f
9 changed files with 28 additions and 42 deletions

View File

@ -2318,18 +2318,6 @@ bool Tokenizer::simplifyTokens1(const std::string &configuration)
createSymbolDatabase();
}
// Use symbol database to identify rvalue references. Split && to & &. This is safe, since it doesn't delete any tokens (which might be referenced by symbol database)
for (const Variable* var : mSymbolDatabase->variableList()) {
if (var && var->isRValueReference()) {
Token* endTok = const_cast<Token*>(var->typeEndToken());
endTok->str("&");
endTok->astOperand1(nullptr);
endTok->astOperand2(nullptr);
endTok->insertToken("&");
endTok->next()->scope(endTok->scope());
}
}
if (mTimerResults) {
Timer t("Tokenizer::simplifyTokens1::setValueType", mSettings->showtime, mTimerResults);
mSymbolDatabase->setValueTypeInTokenList(true);
@ -4636,8 +4624,6 @@ bool Tokenizer::simplifyTokenList1(const char FileName[])
elseif();
SimplifyNamelessRValueReferences();
validate();
list.front()->assignIndexes();
@ -11240,17 +11226,6 @@ void Tokenizer::setPodTypes()
}
}
void Tokenizer::SimplifyNamelessRValueReferences()
{
// Simplify nameless rValue references - named ones are simplified later
for (Token* tok = list.front(); tok; tok = tok->next()) {
if (Token::Match(tok, "&& [,)]")) {
tok->str("&");
tok->insertToken("&");
}
}
}
const Token *Tokenizer::findSQLBlockEnd(const Token *tokSQLStart)
{
const Token *tokLastEnd = nullptr;

View File

@ -154,8 +154,6 @@ public:
*/
bool simplifyTokenList1(const char FileName[]);
void SimplifyNamelessRValueReferences();
/**
* Most aggressive simplification of tokenlist
*

View File

@ -1034,6 +1034,15 @@ static void compileLogicAnd(Token *&tok, AST_state& state)
compileOr(tok, state);
while (tok) {
if (tok->str() == "&&") {
if (!tok->astOperand1()) {
Token* tok2 = tok->next();
if (!tok2)
break;
if (state.cpp && Token::Match(tok2, ",|)")) {
tok = tok2;
break; // rValue reference
}
}
compileBinOp(tok, state, compileOr);
} else break;
}

View File

@ -445,13 +445,13 @@ private:
check("void f() {\n"
" const Token *tok;\n"
" if(a && b && && c && tok && Token::Match(tok, \"5str% foobar\")) {};\n"
" if(a && b && c && tok && Token::Match(tok, \"5str% foobar\")) {};\n"
"}");
ASSERT_EQUALS("[test.cpp:3]: (style) Unnecessary check of \"tok\", match-function already checks if it is null.\n", errout.str());
check("void f() {\n"
" const Token *tok;\n"
" if(a && b && && c && tok && d && Token::Match(tok, \"5str% foobar\")) {};\n"
" if(a && b && c && tok && d && Token::Match(tok, \"5str% foobar\")) {};\n"
"}");
ASSERT_EQUALS("", errout.str());

View File

@ -2221,8 +2221,8 @@ private:
void simplifyTypedef109() {
const char code[] = "typedef int&& rref;\n"
"rref var;";
const char expected[] = "int & & var ;";
"rref var = 0;";
const char expected[] = "int && var ; var = 0 ;";
ASSERT_EQUALS(expected, tok(code));
ASSERT_EQUALS("", errout.str());
}

View File

@ -7269,7 +7269,11 @@ private:
ASSERT_EQUALS("catch...(", testAst("try {} catch (...) {}"));
ASSERT_EQUALS("FooBar(", testAst("void Foo(Bar&);"));
ASSERT_EQUALS("FooBar(", testAst("void Foo(Bar& &);")); // Rvalue reference - simplified from && to & & by real tokenizer
ASSERT_EQUALS("FooBar(", testAst("void Foo(Bar&&);"));
ASSERT_EQUALS("FooBarb&(", testAst("void Foo(Bar& b);"));
ASSERT_EQUALS("FooBarb&&(", testAst("void Foo(Bar&& b);"));
ASSERT_EQUALS("DerivedDerived::(", testAst("Derived::~Derived() {}"));
ASSERT_EQUALS("ifCA_FarReadfilenew(,sizeofobjtype(,(!(", testAst("if (!CA_FarRead(file, (void far *)new, sizeof(objtype)))")); // #5910 - don't hang if C code is parsed as C++