astyle formatting

[ci skip]
This commit is contained in:
Daniel Marjamäki 2021-01-10 14:46:19 +01:00
parent bc3f5554a4
commit f493ce16b3
6 changed files with 277 additions and 275 deletions

View File

@ -281,8 +281,7 @@ QString CppcheckLibraryData::open(QIODevice &file)
} }
if (xmlReader.hasError()) { if (xmlReader.hasError()) {
return xmlReader.errorString(); return xmlReader.errorString();
} } else {
else {
return QString(); return QString();
} }
} }

View File

@ -839,11 +839,11 @@ bool CheckBufferOverrun::analyseWholeProgram1(const std::map<std::string, std::l
const std::list<ErrorMessage::FileLocation> &locationList = const std::list<ErrorMessage::FileLocation> &locationList =
CTU::FileInfo::getErrorPath(CTU::FileInfo::InvalidValueType::bufferOverflow, CTU::FileInfo::getErrorPath(CTU::FileInfo::InvalidValueType::bufferOverflow,
unsafeUsage, unsafeUsage,
callsMap, callsMap,
"Using argument ARG", "Using argument ARG",
&functionCall, &functionCall,
false); false);
if (locationList.empty()) if (locationList.empty())
return false; return false;

View File

@ -592,11 +592,11 @@ bool CheckNullPointer::analyseWholeProgram(const CTU::FileInfo *ctu, const std::
const std::list<ErrorMessage::FileLocation> &locationList = const std::list<ErrorMessage::FileLocation> &locationList =
CTU::FileInfo::getErrorPath(CTU::FileInfo::InvalidValueType::null, CTU::FileInfo::getErrorPath(CTU::FileInfo::InvalidValueType::null,
unsafeUsage, unsafeUsage,
callsMap, callsMap,
"Dereferencing argument ARG that is null", "Dereferencing argument ARG that is null",
nullptr, nullptr,
warning); warning);
if (locationList.empty()) if (locationList.empty())
continue; continue;

View File

@ -1439,11 +1439,11 @@ bool CheckUninitVar::analyseWholeProgram(const CTU::FileInfo *ctu, const std::li
const std::list<ErrorMessage::FileLocation> &locationList = const std::list<ErrorMessage::FileLocation> &locationList =
CTU::FileInfo::getErrorPath(CTU::FileInfo::InvalidValueType::uninit, CTU::FileInfo::getErrorPath(CTU::FileInfo::InvalidValueType::uninit,
unsafeUsage, unsafeUsage,
callsMap, callsMap,
"Using argument ARG", "Using argument ARG",
&functionCall, &functionCall,
false); false);
if (locationList.empty()) if (locationList.empty())
continue; continue;

View File

@ -349,9 +349,15 @@ T asInt(T x)
return x; return x;
} }
MathLib::bigint asInt(float x) { return x; } MathLib::bigint asInt(float x)
{
return x;
}
MathLib::bigint asInt(double x) { return x; } MathLib::bigint asInt(double x)
{
return x;
}
template <class T, class U> template <class T, class U>
static T calculate(const std::string& s, T x, U y) static T calculate(const std::string& s, T x, U y)
@ -4111,98 +4117,97 @@ struct ConditionHandler {
void beforeCondition(TokenList* tokenlist, void beforeCondition(TokenList* tokenlist,
SymbolDatabase* symboldatabase, SymbolDatabase* symboldatabase,
ErrorLogger* errorLogger, ErrorLogger* errorLogger,
const Settings* settings) const const Settings* settings) const {
{
traverseCondition( traverseCondition(
tokenlist, tokenlist,
symboldatabase, symboldatabase,
errorLogger, errorLogger,
settings, settings,
[&](const Condition& cond, Token* tok, const Scope*, const std::vector<const Variable*>&) { [&](const Condition& cond, Token* tok, const Scope*, const std::vector<const Variable*>&) {
if (cond.vartok->exprId() == 0) if (cond.vartok->exprId() == 0)
return; return;
// If condition is known then dont propogate value // If condition is known then dont propogate value
if (tok->hasKnownIntValue()) if (tok->hasKnownIntValue())
return; return;
const Token* top = tok->astTop(); const Token* top = tok->astTop();
if (Token::Match(top, "%assign%")) if (Token::Match(top, "%assign%"))
return; return;
if (Token::simpleMatch(tok->astParent(), "?") && tok->astParent()->isExpandedMacro()) { if (Token::simpleMatch(tok->astParent(), "?") && tok->astParent()->isExpandedMacro()) {
if (settings->debugwarnings) if (settings->debugwarnings)
bailout(tokenlist, bailout(tokenlist,
errorLogger, errorLogger,
tok, tok,
"variable '" + cond.vartok->expressionString() + "', condition is defined in macro"); "variable '" + cond.vartok->expressionString() + "', condition is defined in macro");
return; return;
} }
// if,macro => bailout // if,macro => bailout
if (Token::simpleMatch(top->previous(), "if (") && top->previous()->isExpandedMacro()) { if (Token::simpleMatch(top->previous(), "if (") && top->previous()->isExpandedMacro()) {
if (settings->debugwarnings) if (settings->debugwarnings)
bailout(tokenlist, bailout(tokenlist,
errorLogger, errorLogger,
tok, tok,
"variable '" + cond.vartok->expressionString() + "', condition is defined in macro"); "variable '" + cond.vartok->expressionString() + "', condition is defined in macro");
return; return;
} }
// bailout: for/while-condition, variable is changed in while loop // bailout: for/while-condition, variable is changed in while loop
if (Token::Match(top->previous(), "for|while (") && Token::simpleMatch(top->link(), ") {")) { if (Token::Match(top->previous(), "for|while (") && Token::simpleMatch(top->link(), ") {")) {
// Variable changed in 3rd for-expression // Variable changed in 3rd for-expression
if (Token::simpleMatch(top->previous(), "for (")) { if (Token::simpleMatch(top->previous(), "for (")) {
if (top->astOperand2() && top->astOperand2()->astOperand2() && if (top->astOperand2() && top->astOperand2()->astOperand2() &&
isExpressionChanged( isExpressionChanged(
cond.vartok, top->astOperand2()->astOperand2(), top->link(), settings, tokenlist->isCPP())) { cond.vartok, top->astOperand2()->astOperand2(), top->link(), settings, tokenlist->isCPP())) {
if (settings->debugwarnings) if (settings->debugwarnings)
bailout(tokenlist, bailout(tokenlist,
errorLogger, errorLogger,
tok, tok,
"variable '" + cond.vartok->expressionString() + "' used in loop"); "variable '" + cond.vartok->expressionString() + "' used in loop");
return;
}
}
// Variable changed in loop code
if (Token::Match(top->previous(), "for|while (")) {
const Token* const start = top;
const Token* const block = top->link()->next();
const Token* const end = block->link();
if (isExpressionChanged(cond.vartok, start, end, settings, tokenlist->isCPP())) {
if (settings->debugwarnings)
bailout(tokenlist,
errorLogger,
tok,
"variable '" + cond.vartok->expressionString() + "' used in loop");
return;
}
}
}
std::list<ValueFlow::Value> values = cond.true_values;
if (cond.true_values != cond.false_values)
values.insert(values.end(), cond.false_values.begin(), cond.false_values.end());
// extra logic for unsigned variables 'i>=1' => possible value can also be 0
if (Token::Match(tok, "<|>")) {
values.remove_if([](const ValueFlow::Value& v) {
if (v.isIntValue())
return v.intvalue != 0;
return false;
});
if (cond.vartok->valueType() && cond.vartok->valueType()->sign != ValueType::Sign::UNSIGNED)
return; return;
}
} }
if (values.empty())
// Variable changed in loop code
if (Token::Match(top->previous(), "for|while (")) {
const Token* const start = top;
const Token* const block = top->link()->next();
const Token* const end = block->link();
if (isExpressionChanged(cond.vartok, start, end, settings, tokenlist->isCPP())) {
if (settings->debugwarnings)
bailout(tokenlist,
errorLogger,
tok,
"variable '" + cond.vartok->expressionString() + "' used in loop");
return;
}
}
}
std::list<ValueFlow::Value> values = cond.true_values;
if (cond.true_values != cond.false_values)
values.insert(values.end(), cond.false_values.begin(), cond.false_values.end());
// extra logic for unsigned variables 'i>=1' => possible value can also be 0
if (Token::Match(tok, "<|>")) {
values.remove_if([](const ValueFlow::Value& v) {
if (v.isIntValue())
return v.intvalue != 0;
return false;
});
if (cond.vartok->valueType() && cond.vartok->valueType()->sign != ValueType::Sign::UNSIGNED)
return; return;
Token* startTok = tok->astParent() ? tok->astParent() : tok->previous(); }
reverse(startTok, cond.vartok, values, tokenlist, settings); if (values.empty())
}); return;
Token* startTok = tok->astParent() ? tok->astParent() : tok->previous();
reverse(startTok, cond.vartok, values, tokenlist, settings);
});
} }
void afterCondition(TokenList* tokenlist, void afterCondition(TokenList* tokenlist,
@ -4214,211 +4219,211 @@ struct ConditionHandler {
symboldatabase, symboldatabase,
errorLogger, errorLogger,
settings, settings,
[&](const Condition& cond, Token* tok, const Scope* scope, const std::vector<const Variable*>& vars) { [&](const Condition& cond, Token* tok, const Scope* scope, const std::vector<const Variable*>& vars) {
if (Token::simpleMatch(tok->astParent(), "?")) if (Token::simpleMatch(tok->astParent(), "?"))
return; return;
const Token* top = tok->astTop(); const Token* top = tok->astTop();
std::list<ValueFlow::Value> thenValues; std::list<ValueFlow::Value> thenValues;
std::list<ValueFlow::Value> elseValues; std::list<ValueFlow::Value> elseValues;
if (!Token::Match(tok, "!=|=|(|.") && tok != cond.vartok) { if (!Token::Match(tok, "!=|=|(|.") && tok != cond.vartok) {
thenValues.insert(thenValues.end(), cond.true_values.begin(), cond.true_values.end()); thenValues.insert(thenValues.end(), cond.true_values.begin(), cond.true_values.end());
if (isConditionKnown(tok, false)) if (isConditionKnown(tok, false))
insertImpossible(elseValues, cond.false_values); insertImpossible(elseValues, cond.false_values);
}
if (!Token::Match(tok, "==|!")) {
elseValues.insert(elseValues.end(), cond.false_values.begin(), cond.false_values.end());
if (isConditionKnown(tok, true)) {
insertImpossible(thenValues, cond.true_values);
if (Token::Match(tok, "(|.|%var%") && astIsBool(tok))
insertNegateKnown(thenValues, cond.true_values);
} }
if (!Token::Match(tok, "==|!")) { }
elseValues.insert(elseValues.end(), cond.false_values.begin(), cond.false_values.end());
if (isConditionKnown(tok, true)) { if (cond.inverted)
insertImpossible(thenValues, cond.true_values); std::swap(thenValues, elseValues);
if (Token::Match(tok, "(|.|%var%") && astIsBool(tok))
insertNegateKnown(thenValues, cond.true_values); if (Token::Match(tok->astParent(), "%oror%|&&")) {
Token* parent = tok->astParent();
if (astIsRHS(tok) && parent->astParent() && parent->str() == parent->astParent()->str())
parent = parent->astParent();
else if (!astIsLHS(tok)) {
parent = nullptr;
}
if (parent) {
const std::string& op(parent->str());
std::list<ValueFlow::Value> values;
if (op == "&&")
values = thenValues;
else if (op == "||")
values = elseValues;
if (Token::Match(tok, "==|!="))
changePossibleToKnown(values);
if (!values.empty()) {
bool assign = false;
visitAstNodes(parent->astOperand2(), [&](Token* tok2) {
if (tok2 == tok)
return ChildrenToVisit::done;
if (isSameExpression(
tokenlist->isCPP(), false, cond.vartok, tok2, settings->library, true, false))
setTokenValue(tok2, values.front(), settings);
else if (Token::Match(tok2, "++|--|=") && isSameExpression(tokenlist->isCPP(),
false,
cond.vartok,
tok2->astOperand1(),
settings->library,
true,
false)) {
assign = true;
return ChildrenToVisit::done;
}
return ChildrenToVisit::op1_and_op2;
});
if (assign)
return;
} }
} }
}
if (cond.inverted) {
std::swap(thenValues, elseValues); const Token* tok2 = tok;
std::string op;
if (Token::Match(tok->astParent(), "%oror%|&&")) { bool mixedOperators = false;
Token* parent = tok->astParent(); while (tok2->astParent()) {
if (astIsRHS(tok) && parent->astParent() && parent->str() == parent->astParent()->str()) const Token* parent = tok2->astParent();
parent = parent->astParent(); if (Token::Match(parent, "%oror%|&&")) {
else if (!astIsLHS(tok)) { if (op.empty()) {
parent = nullptr; op = parent->str();
} } else if (op != parent->str()) {
if (parent) { mixedOperators = true;
const std::string& op(parent->str()); break;
std::list<ValueFlow::Value> values;
if (op == "&&")
values = thenValues;
else if (op == "||")
values = elseValues;
if (Token::Match(tok, "==|!="))
changePossibleToKnown(values);
if (!values.empty()) {
bool assign = false;
visitAstNodes(parent->astOperand2(), [&](Token* tok2) {
if (tok2 == tok)
return ChildrenToVisit::done;
if (isSameExpression(
tokenlist->isCPP(), false, cond.vartok, tok2, settings->library, true, false))
setTokenValue(tok2, values.front(), settings);
else if (Token::Match(tok2, "++|--|=") && isSameExpression(tokenlist->isCPP(),
false,
cond.vartok,
tok2->astOperand1(),
settings->library,
true,
false)) {
assign = true;
return ChildrenToVisit::done;
}
return ChildrenToVisit::op1_and_op2;
});
if (assign)
return;
} }
} }
if (parent->str() == "!") {
op = (op == "&&" ? "||" : "&&");
}
tok2 = parent;
} }
if (mixedOperators) {
return;
}
}
if (top && Token::Match(top->previous(), "if|while (") && !top->previous()->isExpandedMacro()) {
// does condition reassign variable?
if (tok != top->astOperand2() && Token::Match(top->astOperand2(), "%oror%|&&") &&
isVariablesChanged(top, top->link(), 0, vars, settings, tokenlist->isCPP())) {
if (settings->debugwarnings)
bailout(tokenlist, errorLogger, tok, "assignment in condition");
return;
}
// start token of conditional code
Token* startTokens[] = {nullptr, nullptr};
// if astParent is "!" we need to invert codeblock
{ {
const Token* tok2 = tok; const Token* tok2 = tok;
std::string op;
bool mixedOperators = false;
while (tok2->astParent()) { while (tok2->astParent()) {
const Token* parent = tok2->astParent(); const Token* parent = tok2->astParent();
if (Token::Match(parent, "%oror%|&&")) { while (parent && parent->str() == "&&")
if (op.empty()) { parent = parent->astParent();
op = parent->str(); if (parent && (parent->str() == "!" || Token::simpleMatch(parent, "== false"))) {
} else if (op != parent->str()) { std::swap(thenValues, elseValues);
mixedOperators = true;
break;
}
}
if (parent->str() == "!") {
op = (op == "&&" ? "||" : "&&");
} }
tok2 = parent; tok2 = parent;
} }
if (mixedOperators) {
return;
}
} }
if (top && Token::Match(top->previous(), "if|while (") && !top->previous()->isExpandedMacro()) { // determine startToken(s)
// does condition reassign variable? if (Token::simpleMatch(top->link(), ") {"))
if (tok != top->astOperand2() && Token::Match(top->astOperand2(), "%oror%|&&") && startTokens[0] = top->link()->next();
isVariablesChanged(top, top->link(), 0, vars, settings, tokenlist->isCPP())) { if (Token::simpleMatch(top->link()->linkAt(1), "} else {"))
startTokens[1] = top->link()->linkAt(1)->tokAt(2);
int changeBlock = -1;
for (int i = 0; i < 2; i++) {
const Token* const startToken = startTokens[i];
if (!startToken)
continue;
std::list<ValueFlow::Value>& values = (i == 0 ? thenValues : elseValues);
valueFlowSetConditionToKnown(tok, values, i == 0);
// TODO: The endToken should not be startTokens[i]->link() in the valueFlowForwardVariable call
if (forward(startTokens[i], startTokens[i]->link(), cond.vartok, values, tokenlist, settings))
changeBlock = i;
changeKnownToPossible(values);
}
// TODO: Values changed in noreturn blocks should not bail
if (changeBlock >= 0 && !Token::simpleMatch(top->previous(), "while (")) {
if (settings->debugwarnings)
bailout(tokenlist,
errorLogger,
startTokens[changeBlock]->link(),
"valueFlowAfterCondition: " + cond.vartok->expressionString() +
" is changed in conditional block");
return;
}
// After conditional code..
if (Token::simpleMatch(top->link(), ") {")) {
Token* after = top->link()->linkAt(1);
const Token* unknownFunction = nullptr;
const bool isWhile =
tok->astParent() && Token::simpleMatch(tok->astParent()->previous(), "while (");
bool dead_if = (!isBreakScope(after) && isWhile) ||
(isReturnScope(after, &settings->library, &unknownFunction) && !isWhile);
bool dead_else = false;
if (!dead_if && unknownFunction) {
if (settings->debugwarnings) if (settings->debugwarnings)
bailout(tokenlist, errorLogger, tok, "assignment in condition"); bailout(tokenlist, errorLogger, unknownFunction, "possible noreturn scope");
return; return;
} }
// start token of conditional code if (Token::simpleMatch(after, "} else {")) {
Token* startTokens[] = {nullptr, nullptr}; after = after->linkAt(2);
unknownFunction = nullptr;
// if astParent is "!" we need to invert codeblock dead_else = isReturnScope(after, &settings->library, &unknownFunction);
{ if (!dead_else && unknownFunction) {
const Token* tok2 = tok;
while (tok2->astParent()) {
const Token* parent = tok2->astParent();
while (parent && parent->str() == "&&")
parent = parent->astParent();
if (parent && (parent->str() == "!" || Token::simpleMatch(parent, "== false"))) {
std::swap(thenValues, elseValues);
}
tok2 = parent;
}
}
// determine startToken(s)
if (Token::simpleMatch(top->link(), ") {"))
startTokens[0] = top->link()->next();
if (Token::simpleMatch(top->link()->linkAt(1), "} else {"))
startTokens[1] = top->link()->linkAt(1)->tokAt(2);
int changeBlock = -1;
for (int i = 0; i < 2; i++) {
const Token* const startToken = startTokens[i];
if (!startToken)
continue;
std::list<ValueFlow::Value>& values = (i == 0 ? thenValues : elseValues);
valueFlowSetConditionToKnown(tok, values, i == 0);
// TODO: The endToken should not be startTokens[i]->link() in the valueFlowForwardVariable call
if (forward(startTokens[i], startTokens[i]->link(), cond.vartok, values, tokenlist, settings))
changeBlock = i;
changeKnownToPossible(values);
}
// TODO: Values changed in noreturn blocks should not bail
if (changeBlock >= 0 && !Token::simpleMatch(top->previous(), "while (")) {
if (settings->debugwarnings)
bailout(tokenlist,
errorLogger,
startTokens[changeBlock]->link(),
"valueFlowAfterCondition: " + cond.vartok->expressionString() +
" is changed in conditional block");
return;
}
// After conditional code..
if (Token::simpleMatch(top->link(), ") {")) {
Token* after = top->link()->linkAt(1);
const Token* unknownFunction = nullptr;
const bool isWhile =
tok->astParent() && Token::simpleMatch(tok->astParent()->previous(), "while (");
bool dead_if = (!isBreakScope(after) && isWhile) ||
(isReturnScope(after, &settings->library, &unknownFunction) && !isWhile);
bool dead_else = false;
if (!dead_if && unknownFunction) {
if (settings->debugwarnings) if (settings->debugwarnings)
bailout(tokenlist, errorLogger, unknownFunction, "possible noreturn scope"); bailout(tokenlist, errorLogger, unknownFunction, "possible noreturn scope");
return; return;
} }
}
if (Token::simpleMatch(after, "} else {")) { if (dead_if && dead_else)
after = after->linkAt(2); return;
unknownFunction = nullptr;
dead_else = isReturnScope(after, &settings->library, &unknownFunction); std::list<ValueFlow::Value> values;
if (!dead_else && unknownFunction) { if (dead_if) {
if (settings->debugwarnings) values = elseValues;
bailout(tokenlist, errorLogger, unknownFunction, "possible noreturn scope"); } else if (dead_else) {
return; values = thenValues;
} } else {
} std::copy_if(thenValues.begin(),
thenValues.end(),
if (dead_if && dead_else) std::back_inserter(values),
return; std::mem_fn(&ValueFlow::Value::isPossible));
std::copy_if(elseValues.begin(),
std::list<ValueFlow::Value> values; elseValues.end(),
if (dead_if) { std::back_inserter(values),
values = elseValues; std::mem_fn(&ValueFlow::Value::isPossible));
} else if (dead_else) { }
values = thenValues;
} else { if (!values.empty()) {
std::copy_if(thenValues.begin(), if ((dead_if || dead_else) && !Token::Match(tok->astParent(), "&&|&")) {
thenValues.end(), valueFlowSetConditionToKnown(tok, values, true);
std::back_inserter(values), valueFlowSetConditionToKnown(tok, values, false);
std::mem_fn(&ValueFlow::Value::isPossible));
std::copy_if(elseValues.begin(),
elseValues.end(),
std::back_inserter(values),
std::mem_fn(&ValueFlow::Value::isPossible));
}
if (!values.empty()) {
if ((dead_if || dead_else) && !Token::Match(tok->astParent(), "&&|&")) {
valueFlowSetConditionToKnown(tok, values, true);
valueFlowSetConditionToKnown(tok, values, false);
}
forward(after, scope->bodyEnd, cond.vartok, values, tokenlist, settings);
} }
forward(after, scope->bodyEnd, cond.vartok, values, tokenlist, settings);
} }
} }
}); }
});
} }
virtual ~ConditionHandler() {} virtual ~ConditionHandler() {}
}; };
@ -4447,8 +4452,7 @@ struct SimpleConditionHandler : ConditionHandler {
const Token* exprTok, const Token* exprTok,
const std::list<ValueFlow::Value>& values, const std::list<ValueFlow::Value>& values,
TokenList* tokenlist, TokenList* tokenlist,
const Settings* settings) const OVERRIDE const Settings* settings) const OVERRIDE {
{
return valueFlowReverse(start, exprTok, values, tokenlist, settings); return valueFlowReverse(start, exprTok, values, tokenlist, settings);
} }
@ -6155,8 +6159,7 @@ struct ContainerConditionHandler : ConditionHandler {
const Token* exprTok, const Token* exprTok,
const std::list<ValueFlow::Value>& values, const std::list<ValueFlow::Value>& values,
TokenList* tokenlist, TokenList* tokenlist,
const Settings* settings) const OVERRIDE const Settings* settings) const OVERRIDE {
{
if (values.empty()) if (values.empty())
return; return;
if (!exprTok->variable()) if (!exprTok->variable())