From 9a5fcddb5dd49c359b0fa8b81920bf859e744638 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 1 Mar 2019 15:47:08 +0100 Subject: [PATCH] Library configuration: Enable configuring the direction of arguments. (#1717) This enhances the library configuration so the direction of function arguments can be specified (in, out, inout). isVariableChangedByFunctionCall() uses this information now to avoid guessing. --- cfg/cppcheck-cfg.rng | 13 +++++++++++++ cfg/std.cfg | 16 ++++++++-------- lib/astutils.cpp | 10 ++++++++++ lib/library.cpp | 11 +++++++++++ lib/library.h | 11 ++++++++++- 5 files changed, 52 insertions(+), 9 deletions(-) diff --git a/cfg/cppcheck-cfg.rng b/cfg/cppcheck-cfg.rng index 318b2541a..2d638920b 100644 --- a/cfg/cppcheck-cfg.rng +++ b/cfg/cppcheck-cfg.rng @@ -163,6 +163,11 @@ + + + + + @@ -425,6 +430,14 @@ 20 + + + + in + out + inout + + diff --git a/cfg/std.cfg b/cfg/std.cfg index b64c2c2af..a14b07c76 100644 --- a/cfg/std.cfg +++ b/cfg/std.cfg @@ -52,7 +52,7 @@ arg1>0?arg1:-arg1 false - + @@ -448,10 +448,10 @@ false - + - + @@ -4115,7 +4115,7 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + @@ -4505,12 +4505,12 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + - + @@ -5734,12 +5734,12 @@ The obsolete function 'gets' is called. With 'gets' you'll get a buffer overrun false - + - + diff --git a/lib/astutils.cpp b/lib/astutils.cpp index 63319b2e5..bcd78c1a5 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -880,6 +880,16 @@ bool isVariableChangedByFunctionCall(const Token *tok, const Settings *settings, } if (!tok->function()) { + // Check if direction (in, out, inout) is specified in the library configuration and use that + if (!addressOf && settings) { + const Library::ArgumentChecks::Direction argDirection = settings->library.getArgDirection(tok, 1 + argnr); + if (argDirection == Library::ArgumentChecks::Direction::DIR_IN) + return false; + else if (argDirection == Library::ArgumentChecks::Direction::DIR_OUT || + argDirection == Library::ArgumentChecks::Direction::DIR_INOUT) + return true; + } + // if the library says 0 is invalid // => it is assumed that parameter is an in parameter (TODO: this is a bad heuristic) if (!addressOf && settings && settings->library.isnullargbad(tok, 1+argnr)) diff --git a/lib/library.cpp b/lib/library.cpp index abbe760de..f4ab94f65 100644 --- a/lib/library.cpp +++ b/lib/library.cpp @@ -581,6 +581,17 @@ Library::Error Library::loadFunction(const tinyxml2::XMLElement * const node, co ArgumentChecks &ac = func.argumentChecks[nr]; ac.optional = functionnode->Attribute("default") != nullptr; ac.variadic = bVariadicArg; + const char * const argDirection = functionnode->Attribute("direction"); + if (argDirection) { + const size_t argDirLen = strlen(argDirection); + if (!strncmp(argDirection, "in", argDirLen)) { + ac.direction = ArgumentChecks::Direction::DIR_IN; + } else if (!strncmp(argDirection, "out", argDirLen)) { + ac.direction = ArgumentChecks::Direction::DIR_OUT; + } else if (!strncmp(argDirection, "inout", argDirLen)) { + ac.direction = ArgumentChecks::Direction::DIR_INOUT; + } + } for (const tinyxml2::XMLElement *argnode = functionnode->FirstChildElement(); argnode; argnode = argnode->NextSiblingElement()) { const std::string argnodename = argnode->Name(); if (argnodename == "not-bool") diff --git a/lib/library.h b/lib/library.h index 4c5338f27..bd4f16848 100644 --- a/lib/library.h +++ b/lib/library.h @@ -227,7 +227,8 @@ public: strz(false), optional(false), variadic(false), - iteratorInfo() { + iteratorInfo(), + direction(DIR_UNKNOWN) { } bool notbool; @@ -259,6 +260,9 @@ public: int arg2; }; std::vector minsizes; + + enum Direction { DIR_IN, DIR_OUT, DIR_INOUT, DIR_UNKNOWN }; + Direction direction; }; @@ -320,6 +324,11 @@ public: return arg ? &arg->minsizes : nullptr; } + ArgumentChecks::Direction getArgDirection(const Token *ftok, int argnr) const { + const ArgumentChecks *arg = getarg(ftok, argnr); + return arg ? arg->direction : ArgumentChecks::Direction::DIR_UNKNOWN; + } + bool markupFile(const std::string &path) const; bool processMarkupAfterCode(const std::string &path) const;