diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index c65542da4..cc7f7a277 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -3661,52 +3661,7 @@ bool Tokenizer::simplifyTokenList2() simplifyOffsetPointerDereference(); // Replace "&str[num]" => "(str + num)" - std::set pod; - for (const Token *tok = list.front(); tok; tok = tok->next()) { - if (tok->isStandardType()) { - tok = tok->next(); - while (tok && (tok->str() == "*" || tok->isName())) { - if (tok->varId() > 0) { - pod.insert(tok->varId()); - break; - } - tok = tok->next(); - } - if (!tok) - break; - } - } - - for (Token *tok = list.front(); tok; tok = tok->next()) { - if (!Token::Match(tok, "%num%|%name%|]|)") && - (Token::Match(tok->next(), "& %name% [ %num%|%name% ] !!["))) { - tok = tok->next(); - - if (tok->next()->varId()) { - if (pod.find(tok->next()->varId()) == pod.end()) { - tok = tok->tokAt(5); - if (!tok) { - syntaxError(tok); - return false; - } - continue; - } - } - - // '&' => '(' - tok->str("("); - - tok = tok->next(); - // '[' => '+' - tok->deleteNext(); - tok->insertToken("+"); - - tok = tok->tokAt(3); - //remove ']' - tok->str(")"); - Token::createMutualLinks(tok->tokAt(-4), tok); - } - } + simplifyOffsetPointerReference(); removeRedundantAssignment(); @@ -3729,6 +3684,14 @@ bool Tokenizer::simplifyTokenList2() simplifyIfAndWhileAssign(); // Could be affected by simplifyIfNot + // replace strlen(str) + for (Token *tok = list.front(); tok; tok = tok->next()) { + if (Token::Match(tok, "strlen ( %str% )")) { + tok->str(MathLib::toString(Token::getStrLength(tok->tokAt(2)))); + tok->deleteNext(3); + } + } + bool modified = true; while (modified) { if (_settings->terminated()) @@ -3738,22 +3701,16 @@ bool Tokenizer::simplifyTokenList2() modified |= simplifyConditions(); modified |= simplifyFunctionReturn(); modified |= simplifyKnownVariables(); - - // replace strlen(str) - for (Token *tok = list.front(); tok; tok = tok->next()) { - if (Token::Match(tok, "strlen ( %str% )")) { - tok->str(MathLib::toString(Token::getStrLength(tok->tokAt(2)))); - tok->deleteNext(3); - modified = true; - } - } + modified |= simplifyStrlen(); modified |= removeRedundantConditions(); modified |= simplifyRedundantParentheses(); modified |= simplifyConstTernaryOp(); modified |= simplifyCalculations(); + validate(); } + // simplify redundant loops simplifyWhile0(); removeRedundantFor(); @@ -7312,6 +7269,55 @@ void Tokenizer::simplifyOffsetPointerDereference() } } +void Tokenizer::simplifyOffsetPointerReference() +{ + std::set pod; + for (const Token *tok = list.front(); tok; tok = tok->next()) { + if (tok->isStandardType()) { + tok = tok->next(); + while (tok && (tok->str() == "*" || tok->isName())) { + if (tok->varId() > 0) { + pod.insert(tok->varId()); + break; + } + tok = tok->next(); + } + if (!tok) + break; + } + } + + for (Token *tok = list.front(); tok; tok = tok->next()) { + if (!Token::Match(tok, "%num%|%name%|]|)") && + (Token::Match(tok->next(), "& %name% [ %num%|%name% ] !!["))) { + tok = tok->next(); + + if (tok->next()->varId()) { + if (pod.find(tok->next()->varId()) == pod.end()) { + tok = tok->tokAt(5); + if (!tok) { + syntaxError(tok); + } + continue; + } + } + + // '&' => '(' + tok->str("("); + + tok = tok->next(); + // '[' => '+' + tok->deleteNext(); + tok->insertToken("+"); + + tok = tok->tokAt(3); + //remove ']' + tok->str(")"); + Token::createMutualLinks(tok->tokAt(-4), tok); + } + } +} + void Tokenizer::simplifyNestedStrcat() { for (Token *tok = list.front(); tok; tok = tok->next()) { @@ -10417,6 +10423,20 @@ void Tokenizer::simplifyMathExpressions() } } +bool Tokenizer::simplifyStrlen() +{ + // replace strlen(str) + bool modified=false; + for (Token *tok = list.front(); tok; tok = tok->next()) { + if (Token::Match(tok, "strlen ( %str% )")) { + tok->str(MathLib::toString(Token::getStrLength(tok->tokAt(2)))); + tok->deleteNext(3); + modified=true; + } + } + return modified; +} + void Tokenizer::reportError(const Token* tok, const Severity::SeverityType severity, const std::string& id, const std::string& msg, bool inconclusive) const { const std::list callstack(1, tok); diff --git a/lib/tokenize.h b/lib/tokenize.h index 6ea5b7d2c..755805cd9 100644 --- a/lib/tokenize.h +++ b/lib/tokenize.h @@ -186,6 +186,12 @@ public: */ void simplifyOffsetPointerDereference(); + /** + * Simplify referencing a pointer offset: + * "Replace "&str[num]" => "(str + num)" + */ + void simplifyOffsetPointerReference(); + /** Insert array size where it isn't given */ void arraySize(); @@ -691,6 +697,12 @@ public: */ void simplifyDeprecated(); + /** + * Replace strlen(str) + * @return true if any replacement took place, false else + * */ + bool simplifyStrlen(); + /** * check for duplicate enum definition */ diff --git a/test/testgarbage.cpp b/test/testgarbage.cpp index c5f86866c..6dda2a9f5 100644 --- a/test/testgarbage.cpp +++ b/test/testgarbage.cpp @@ -127,6 +127,7 @@ private: TEST_CASE(garbageCode85); TEST_CASE(garbageCode86); TEST_CASE(garbageCode87); + TEST_CASE(garbageCode88); TEST_CASE(garbageValueFlow); TEST_CASE(garbageSymbolDatabase); @@ -697,6 +698,10 @@ private: ASSERT_THROW(checkCode("((X (128))) (int a) { v[ = {} (x 42) a] += }"), InternalError); // do not crash } + void garbageCode88() { // #6786 + ASSERT_THROW(checkCode("( ) { ( 0 ) { ( ) } } g ( ) { i( ( false ?) ( ) : 1 ) ; } ;"), InternalError); // do not crash + } + void garbageValueFlow() { // #6089 const char* code = "{} int foo(struct, x1, struct x2, x3, int, x5, x6, x7)\n"