From c39fab721db28cea94d561a900233fd099193c61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Marjam=C3=A4ki?= Date: Sat, 8 Jan 2011 10:20:29 +0100 Subject: [PATCH] Writing rules: Added one more example for the C++ intro --- man/writing-rules-3.docbook | 107 ++++++++++++++++++++++++++++++++++-- 1 file changed, 103 insertions(+), 4 deletions(-) diff --git a/man/writing-rules-3.docbook b/man/writing-rules-3.docbook index 787ff9910..29e369d98 100644 --- a/man/writing-rules-3.docbook +++ b/man/writing-rules-3.docbook @@ -73,7 +73,10 @@ void CheckOther::divisionByZero() // Report error void CheckOther::divisionByZeroError() { - reportError(tok, Severity::error, "divisionByZero", "Division by zero"); + reportError(tok, // location + Severity::error, // severity + "divisionByZero", // id + "Division by zero"); // message } The Token::Match matches tokens against @@ -111,7 +114,8 @@ void CheckOther::divisionByZeroError() if ( %var% ) { free ( %var% ) ; } - Any variable name is matched by %var%. + The %var% pattern is used to match any variable + name. Here is a C++ function: @@ -143,10 +147,105 @@ void CheckOther::dealloc() // Report warning void CheckOther::deallocWarning() { - reportError(tok, Severity::warning, "dealloc", "Redundant condition before deallocation"); + reportError(tok, // location + Severity::warning, // severity + "dealloc", // id + "Redundant condition"); // message } The strAt function is used to fetch strings from the token list. The - parameter specifies the token offset. + parameter specifies the token offset. The result for "tok->tokAt(1)" is + the same as for "tok->next()". + + +
+ Validate function parameters + + Sometimes it is known that a function can't handle certain + parameters. Here is an example rule that checks that the parameters for + strtol or strtoul are valid: + + //--------------------------------------------------------------------------- +// strtol(str, 0, radix) <- radix must be 0 or 2-36 +//--------------------------------------------------------------------------- + +void CheckOther::invalidFunctionUsage() +{ + // Loop through all tokens + for (const Token *tok = _tokenizer->tokens(); tok; tok = tok->next()) + { + // Is there a function call for strtol or strtoul? + if (!Token::Match(tok, "strtol|strtoul (")) + continue; + + // Locate the third parameter of the function call.. + + // Counter that counts the parameters. + int param = 1; + + // Scan the function call tokens. The "tok->tokAt(2)" returns + // the token after the "(" + for (const Token *tok2 = tok->tokAt(2); tok2; tok2 = tok2->next()) + { + // If a "(" is found then jump to the corresponding ")" + if (tok2->str() == "(") + tok2 = tok2->link(); + + // End of function call. + else if (tok2->str() == ")") + break; + + // Found a ",". increment param counter + else if (tok2->str() == ",") + { + ++param; + + // If the param is 3 then check if the parameter is valid + if (param == 3) + { + if (Token::Match(tok2, ", %num% )")) + { + // convert next token into a number + MathLib::bigint radix; + radix = MathLib::toLongNumber(tok2->strAt(1)); + + // invalid radix? + if (!(radix == 0 || (radix >= 2 && radix <= 36))) + { + dangerousUsageStrtolError(tok2); + } + } + break; + } + } + } + } +} + +void CheckOther::dangerousUsageStrtolError(const Token *tok) +{ + reportError(tok, // location + Severity::error, // severity + "dangerousUsageStrtol", // id + "Invalid radix"); // message +} + + The link() member function is used to find the corresponding ( ) [ ] + or { } token. + + The inner loop is not necessary if you just want to get the last + parameter. This code will check if the last parameter is + numerical.. + + .. + // Is there a function call? + if (!Token::Match(tok, "do_something (")) + continue; + + if (Token::Match(tok->next()->link()->tokAt(-2), "(|, %num% )")) + ... + + The pattern (|, can also be written as + [(,].