Fix 10659: FP knownConditionTrueFalse - C++17 structured binding (#3662)
This commit is contained in:
parent
af289c8357
commit
71a44395c8
|
@ -846,6 +846,16 @@ static bool hasUnknownVars(const Token* startTok)
|
|||
return result;
|
||||
}
|
||||
|
||||
static bool isStructuredBindingVariable(const Variable* var)
|
||||
{
|
||||
if (!var)
|
||||
return false;
|
||||
const Token* tok = var->nameToken();
|
||||
while (Token::Match(tok->astParent(), "[|,"))
|
||||
tok = tok->astParent();
|
||||
return Token::simpleMatch(tok, "[");
|
||||
}
|
||||
|
||||
/// This takes a token that refers to a variable and it will return the token
|
||||
/// to the expression that the variable is assigned to. If its not valid to
|
||||
/// make such substitution then it will return the original token.
|
||||
|
@ -879,6 +889,8 @@ static const Token * followVariableExpression(const Token * tok, bool cpp, const
|
|||
return tok;
|
||||
if (var->isArgument())
|
||||
return tok;
|
||||
if (isStructuredBindingVariable(var))
|
||||
return tok;
|
||||
const Token * lastTok = precedes(tok, end) ? end : tok;
|
||||
// If this is in a loop then check if variables are modified in the entire scope
|
||||
const Token * endToken = (isInLoopCondition(tok) || isInLoopCondition(varTok) || var->scope() != tok->scope()) ? var->scope()->bodyEnd : lastTok;
|
||||
|
@ -931,7 +943,7 @@ std::vector<ReferenceToken> followAllReferences(const Token* tok,
|
|||
return {{tok, std::move(errors)}};
|
||||
const Variable *var = tok->variable();
|
||||
if (var && var->declarationId() == tok->varId()) {
|
||||
if (var->nameToken() == tok) {
|
||||
if (var->nameToken() == tok || isStructuredBindingVariable(var)) {
|
||||
return {{tok, std::move(errors)}};
|
||||
} else if (var->isReference() || var->isRValueReference()) {
|
||||
if (!var->declEndToken())
|
||||
|
|
|
@ -3850,6 +3850,14 @@ private:
|
|||
" while (is_running) {}\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
|
||||
// #10659
|
||||
check("auto func(const std::tuple<int, int>& t) {\n"
|
||||
" auto& [foo, bar] = t;\n"
|
||||
" std::cout << foo << bar << std::endl;\n"
|
||||
" return foo < bar;\n"
|
||||
"}\n");
|
||||
ASSERT_EQUALS("", errout.str());
|
||||
}
|
||||
|
||||
void alwaysTrueSymbolic()
|
||||
|
|
Loading…
Reference in New Issue