Skip to content

Commit b8b0280

Browse files
authored
utilize returns_nonnull function attribute (danmar#6759)
1 parent b8f80a9 commit b8b0280

10 files changed

Lines changed: 27 additions & 42 deletions

lib/astutils.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -991,7 +991,7 @@ static const Token * getVariableInitExpression(const Variable * var)
991991
const Token* isInLoopCondition(const Token* tok)
992992
{
993993
const Token* top = tok->astTop();
994-
return top && Token::Match(top->previous(), "for|while (") ? top : nullptr;
994+
return Token::Match(top->previous(), "for|while (") ? top : nullptr;
995995
}
996996

997997
/// If tok2 comes after tok1

lib/checkcondition.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -834,8 +834,6 @@ static std::string innerSmtString(const Token * tok)
834834
{
835835
if (!tok)
836836
return "if";
837-
if (!tok->astTop())
838-
return "if";
839837
const Token * top = tok->astTop();
840838
if (top->str() == "(" && top->astOperand1())
841839
return top->astOperand1()->str();
@@ -1119,7 +1117,7 @@ static std::string conditionString(const Token * tok)
11191117

11201118
static bool isIfConstexpr(const Token* tok) {
11211119
const Token* const top = tok->astTop();
1122-
return top && Token::simpleMatch(top->astOperand1(), "if") && top->astOperand1()->isConstexpr();
1120+
return Token::simpleMatch(top->astOperand1(), "if") && top->astOperand1()->isConstexpr();
11231121
}
11241122

11251123
void CheckCondition::checkIncorrectLogicOperator()

lib/checkother.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2307,8 +2307,6 @@ static const Token * getSingleExpressionInBlock(const Token * tok)
23072307
if (!tok)
23082308
return nullptr;
23092309
const Token * top = tok->astTop();
2310-
if (!top)
2311-
return nullptr;
23122310
const Token * nextExpression = nextAfterAstRightmostLeaf(top);
23132311
if (!Token::simpleMatch(nextExpression, "; }"))
23142312
return nullptr;

lib/checkstl.cpp

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1613,22 +1613,8 @@ static const Token* skipLocalVars(const Token* const tok)
16131613
if (Token::simpleMatch(tok, "{"))
16141614
return skipLocalVars(tok->next());
16151615

1616-
const Token *top = tok->astTop();
1617-
if (!top) {
1618-
const Token *semi = Token::findsimplematch(tok, ";");
1619-
if (!semi)
1620-
return tok;
1621-
if (!Token::Match(semi->previous(), "%var% ;"))
1622-
return tok;
1623-
const Token *varTok = semi->previous();
1624-
const Variable *var = varTok->variable();
1625-
if (!var)
1626-
return tok;
1627-
if (var->nameToken() != varTok)
1628-
return tok;
1629-
return skipLocalVars(semi->next());
1630-
}
16311616
if (tok->isAssignmentOp()) {
1617+
const Token *top = tok->astTop();
16321618
const Token *varTok = top->astOperand1();
16331619
const Variable *var = varTok->variable();
16341620
if (!var)

lib/config.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,16 @@
121121
# define DEPRECATED
122122
#endif
123123

124+
// TODO: GCC apparently also supports this but there is no documentation on it
125+
// returns_nonnull
126+
#if __has_cpp_attribute (gnu::returns_nonnull)
127+
# define RET_NONNULL [[gnu::returns_nonnull]]
128+
#elif (defined(__clang__) && ((__clang_major__ > 3) || ((__clang_major__ == 3) && (__clang_minor__ >= 7))))
129+
# define RET_NONNULL __attribute__((returns_nonnull))
130+
#else
131+
# define RET_NONNULL
132+
#endif
133+
124134
#define REQUIRES(msg, ...) class=typename std::enable_if<__VA_ARGS__::value>::type
125135

126136
#include <string>

lib/forwardanalyzer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,7 @@ namespace {
585585
return Break(Analyzer::Terminate::Bail);
586586
} else if (tok->str() == ";" && tok->astParent()) {
587587
Token* top = tok->astTop();
588-
if (top && Token::Match(top->previous(), "for|while (") && Token::simpleMatch(top->link(), ") {")) {
588+
if (Token::Match(top->previous(), "for|while (") && Token::simpleMatch(top->link(), ") {")) {
589589
Token* endCond = top->link();
590590
Token* endBlock = endCond->linkAt(1);
591591
Token* condTok = getCondTok(top);

lib/programmemory.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ void ProgramMemoryState::assume(const Token* tok, bool b, bool isEmpty)
509509
programMemoryParseCondition(pm, tok, nullptr, *settings, b);
510510
const Token* origin = tok;
511511
const Token* top = tok->astTop();
512-
if (top && Token::Match(top->previous(), "for|while|if (") && !Token::simpleMatch(tok->astParent(), "?")) {
512+
if (Token::Match(top->previous(), "for|while|if (") && !Token::simpleMatch(tok->astParent(), "?")) {
513513
origin = top->link()->next();
514514
if (!b && origin->link()) {
515515
origin = origin->link();
@@ -1727,8 +1727,6 @@ namespace {
17271727
return {unknown()};
17281728
for (const Token* tok = scope->bodyStart->next(); precedes(tok, scope->bodyEnd); tok = tok->next()) {
17291729
const Token* top = tok->astTop();
1730-
if (!top)
1731-
return {unknown()};
17321730

17331731
if (Token::simpleMatch(top, "return") && top->astOperand1())
17341732
return {execute(top->astOperand1())};

lib/reverseanalyzer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -295,7 +295,7 @@ namespace {
295295
if (!condTok)
296296
break;
297297
Analyzer::Action condAction = analyzeRecursive(condTok);
298-
const bool inLoop = condTok->astTop() && Token::Match(condTok->astTop()->previous(), "for|while (");
298+
const bool inLoop = Token::Match(condTok->astTop()->previous(), "for|while (");
299299
// Evaluate condition of for and while loops first
300300
if (inLoop) {
301301
if (Token::findmatch(tok->link(), "goto|break", tok))

lib/token.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -919,9 +919,9 @@ class CPPCHECKLIB Token {
919919
* @param prepend Insert the new token before this token when it's not
920920
* the first one on the tokens list.
921921
*/
922-
Token* insertToken(const std::string& tokenStr, const std::string& originalNameStr = emptyString, const std::string& macroNameStr = emptyString, bool prepend = false);
922+
RET_NONNULL Token* insertToken(const std::string& tokenStr, const std::string& originalNameStr = emptyString, const std::string& macroNameStr = emptyString, bool prepend = false);
923923

924-
Token* insertTokenBefore(const std::string& tokenStr, const std::string& originalNameStr = emptyString, const std::string& macroNameStr = emptyString)
924+
RET_NONNULL Token* insertTokenBefore(const std::string& tokenStr, const std::string& originalNameStr = emptyString, const std::string& macroNameStr = emptyString)
925925
{
926926
return insertToken(tokenStr, originalNameStr, macroNameStr, true);
927927
}
@@ -1224,22 +1224,22 @@ class CPPCHECKLIB Token {
12241224
/**
12251225
* @return the first token of the next argument. Does only work on argument
12261226
* lists. Requires that Tokenizer::createLinks2() has been called before.
1227-
* Returns 0, if there is no next argument.
1227+
* Returns nullptr, if there is no next argument.
12281228
*/
12291229
const Token* nextArgument() const;
12301230
Token *nextArgument();
12311231

12321232
/**
12331233
* @return the first token of the next argument. Does only work on argument
12341234
* lists. Should be used only before Tokenizer::createLinks2() was called.
1235-
* Returns 0, if there is no next argument.
1235+
* Returns nullptr, if there is no next argument.
12361236
*/
12371237
const Token* nextArgumentBeforeCreateLinks2() const;
12381238

12391239
/**
12401240
* @return the first token of the next template argument. Does only work on template argument
12411241
* lists. Requires that Tokenizer::createLinks2() has been called before.
1242-
* Returns 0, if there is no next argument.
1242+
* Returns nullptr, if there is no next argument.
12431243
*/
12441244
const Token* nextTemplateArgument() const;
12451245

@@ -1477,14 +1477,14 @@ class CPPCHECKLIB Token {
14771477
return nullptr;
14781478

14791479
}
1480-
Token *astTop() {
1480+
RET_NONNULL Token *astTop() {
14811481
Token *ret = this;
14821482
while (ret->mImpl->mAstParent)
14831483
ret = ret->mImpl->mAstParent;
14841484
return ret;
14851485
}
14861486

1487-
const Token *astTop() const {
1487+
RET_NONNULL const Token *astTop() const {
14881488
const Token *ret = this;
14891489
while (ret->mImpl->mAstParent)
14901490
ret = ret->mImpl->mAstParent;

lib/valueflow.cpp

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -635,7 +635,7 @@ static bool isConditionKnown(const Token* tok, bool then)
635635
while (parent && (parent->str() == op || parent->str() == "!" || parent->isCast()))
636636
parent = parent->astParent();
637637
const Token* top = tok->astTop();
638-
if (top && Token::Match(top->previous(), "if|while|for ("))
638+
if (Token::Match(top->previous(), "if|while|for ("))
639639
return parent == top || Token::simpleMatch(parent, ";");
640640
return parent && parent->str() != op;
641641
}
@@ -2372,7 +2372,7 @@ const Token* ValueFlow::getEndOfExprScope(const Token* tok, const Scope* default
23722372
end = varEnd;
23732373

23742374
const Token* top = var->nameToken()->astTop();
2375-
if (top && Token::simpleMatch(top->tokAt(-1), "if (")) { // variable declared in if (...)
2375+
if (Token::simpleMatch(top->tokAt(-1), "if (")) { // variable declared in if (...)
23762376
const Token* elseTok = top->link()->linkAt(1);
23772377
if (Token::simpleMatch(elseTok, "} else {") && tok->scope()->isNestedIn(elseTok->tokAt(2)->scope()))
23782378
end = tok->scope()->bodyEnd;
@@ -4753,8 +4753,6 @@ struct ConditionHandler {
47534753
continue;
47544754

47554755
const Token* top = tok->astTop();
4756-
if (!top)
4757-
continue;
47584756

47594757
if (!Token::Match(top->previous(), "if|while|for (") && !Token::Match(tok->astParent(), "&&|%oror%|?|!"))
47604758
continue;
@@ -4929,8 +4927,6 @@ struct ConditionHandler {
49294927
const Settings& settings,
49304928
const std::set<const Scope*>& skippedFunctions) const {
49314929
traverseCondition(symboldatabase, settings, skippedFunctions, [&](const Condition& cond, Token* condTok, const Scope* scope) {
4932-
Token* top = condTok->astTop();
4933-
49344930
const MathLib::bigint path = cond.getPath();
49354931
const bool allowKnown = path == 0;
49364932

@@ -5005,8 +5001,7 @@ struct ConditionHandler {
50055001
}
50065002
}
50075003

5008-
if (!top)
5009-
return;
5004+
Token* top = condTok->astTop();
50105005

50115006
if (top->previous()->isExpandedMacro()) {
50125007
for (std::list<ValueFlow::Value>* values : {&thenValues, &elseValues}) {
@@ -7088,7 +7083,7 @@ static void valueFlowContainerSize(const TokenList& tokenlist,
70887083
!Token::Match(nameToken, "%name% ("))
70897084
continue;
70907085
}
7091-
if (nameToken->astTop() && Token::Match(nameToken->astTop()->previous(), "for|while"))
7086+
if (Token::Match(nameToken->astTop()->previous(), "for|while"))
70927087
known = !isVariableChanged(var, settings);
70937088
std::vector<ValueFlow::Value> values{ValueFlow::Value{size}};
70947089
values.back().valueType = ValueFlow::Value::ValueType::CONTAINER_SIZE;

0 commit comments

Comments
 (0)