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;
|
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
|
/// 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
|
/// to the expression that the variable is assigned to. If its not valid to
|
||||||
/// make such substitution then it will return the original token.
|
/// 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;
|
return tok;
|
||||||
if (var->isArgument())
|
if (var->isArgument())
|
||||||
return tok;
|
return tok;
|
||||||
|
if (isStructuredBindingVariable(var))
|
||||||
|
return tok;
|
||||||
const Token * lastTok = precedes(tok, end) ? end : 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
|
// 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;
|
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)}};
|
return {{tok, std::move(errors)}};
|
||||||
const Variable *var = tok->variable();
|
const Variable *var = tok->variable();
|
||||||
if (var && var->declarationId() == tok->varId()) {
|
if (var && var->declarationId() == tok->varId()) {
|
||||||
if (var->nameToken() == tok) {
|
if (var->nameToken() == tok || isStructuredBindingVariable(var)) {
|
||||||
return {{tok, std::move(errors)}};
|
return {{tok, std::move(errors)}};
|
||||||
} else if (var->isReference() || var->isRValueReference()) {
|
} else if (var->isReference() || var->isRValueReference()) {
|
||||||
if (!var->declEndToken())
|
if (!var->declEndToken())
|
||||||
|
|
|
@ -3850,6 +3850,14 @@ private:
|
||||||
" while (is_running) {}\n"
|
" while (is_running) {}\n"
|
||||||
"}\n");
|
"}\n");
|
||||||
ASSERT_EQUALS("", errout.str());
|
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()
|
void alwaysTrueSymbolic()
|
||||||
|
|
Loading…
Reference in New Issue