62 return tokenizer.
list.
file(function->tokenDef) +
':' + std::to_string(function->tokenDef->linenr()) +
':' + std::to_string(function->tokenDef->column());
66 : fileName(tokenizer.list.file(tok))
67 , lineNumber(tok->linenr())
68 , column(tok->column())
73 std::ostringstream out;
77 out << functionCall.toXmlString();
82 out << nestedCall.toXmlString() <<
"\n";
90 std::ostringstream out;
102 std::ostringstream out;
103 out <<
"<function-call"
110 if (callValuePath.empty())
120 out <<
"</function-call>";
127 std::ostringstream out;
128 out <<
"<function-call"
138 std::ostringstream out;
139 out <<
" <unsafe-usage"
146 <<
" " <<
ATTR_VALUE <<
"=\"" << value <<
"\""
151 std::string
CTU::toString(
const std::list<CTU::FileInfo::UnsafeUsage> &unsafeUsage)
153 std::ostringstream ret;
161 , callFunctionName(callToken->next()->astOperand1()->expressionString())
170 static std::string
readAttrString(
const tinyxml2::XMLElement *e,
const char *attr,
bool *error)
172 const char *value = e->Attribute(attr);
175 return value ? value :
"";
178 static long long readAttrInt(
const tinyxml2::XMLElement *e,
const char *attr,
bool *error)
181 const bool err = (e->QueryInt64Attribute(attr, &value) != tinyxml2::XML_SUCCESS);
201 if (!loadBaseFromXml(xmlElement))
208 warning = w && std::strcmp(w,
"true") == 0;
209 for (
const tinyxml2::XMLElement *e2 = xmlElement->FirstChildElement(); !
error && e2; e2 = e2->NextSiblingElement()) {
210 if (std::strcmp(e2->Name(),
"path") != 0)
224 if (!loadBaseFromXml(xmlElement))
234 for (
const tinyxml2::XMLElement *e = xmlElement->FirstChildElement(); e; e = e->NextSiblingElement()) {
235 if (std::strcmp(e->Name(),
"function-call") == 0) {
239 }
else if (std::strcmp(e->Name(),
"nested-call") == 0) {
249 std::map<std::string, std::list<const CTU::FileInfo::CallBase *>> ret;
251 ret[nc.callId].push_back(&nc);
253 ret[fc.callId].push_back(&fc);
259 std::list<CTU::FileInfo::UnsafeUsage> ret;
260 for (
const tinyxml2::XMLElement *e = xmlElement->FirstChildElement(); e; e = e->NextSiblingElement()) {
261 if (std::strcmp(e->Name(),
"unsafe-usage") != 0)
274 ret.push_back(std::move(unsafeUsage));
285 if (tok2->variable() != argvar)
290 const Token *prev = tok2;
291 while (prev && prev->
str() !=
"(") {
294 else if (prev->
str() ==
",")
323 if (tok->str() !=
"(" || !tok->astOperand1() || !tok->astOperand2())
325 const Function* tokFunction = tok->astOperand1()->function();
328 const std::vector<const Token *> args(
getArguments(tok->previous()));
329 for (
int argnr = 0; argnr < args.size(); ++argnr) {
330 const Token *argtok = args[argnr];
334 if ((!value.isIntValue() || value.intvalue != 0 || value.isInconclusive()) && !value.isBufferSizeValue())
337 if (value.isImpossible())
347 functionCall.
warning = !value.errorSeverity();
349 const std::string& file = tokenizer.
list.
file(i.first);
350 const std::string& info = i.second;
351 const int line = i.first->linenr();
352 const int column = i.first->column();
356 fileInfo->functionCalls.push_back(std::move(functionCall));
370 fileInfo->functionCalls.push_back(std::move(functionCall));
383 fileInfo->functionCalls.push_back(std::move(functionCall));
386 auto isAddressOfArg = [](
const Token* argtok) ->
const Token* {
394 auto isReferenceArg = [&](
const Token* argtok) ->
const Token* {
400 const Token* addr = isAddressOfArg(argtok);
401 argtok = addr ? addr : isReferenceArg(argtok);
402 if (!argtok || argtok->
values().size() != 1U)
418 fileInfo->functionCalls.push_back(std::move(functionCall));
425 for (
int argnr = 0; argnr < scopeFunction->
argCount(); ++argnr) {
430 nestedCall.
myArgNr = argnr + 1;
432 fileInfo->nestedCalls.push_back(std::move(nestedCall));
442 std::list<std::pair<const Token *, MathLib::bigint>> ret;
448 tok2 = tok2->linkAt(1);
458 tok2 = tok2->findExpressionStartEndTokens().second;
461 if (tok2->variable() != argvar)
466 ret.emplace_back(tok2, value);
474 std::list<CTU::FileInfo::UnsafeUsage> unsafeUsage;
485 for (
int argnr = 0; argnr <
function->argCount(); ++argnr) {
487 const Token *tok = v.first;
501 const std::map<std::string, std::list<const CTU::FileInfo::CallBase *>> &callsMap,
509 const std::map<std::string, std::list<const CTU::FileInfo::CallBase *>>::const_iterator it = callsMap.find(callId);
510 if (it == callsMap.end())
519 if (!
warning && functionCall->warning)
521 switch (invalidValue) {
533 if (unsafeValue < 0 || (unsafeValue >= functionCall->callArgValue && functionCall->callArgValue >= 0))
537 path[index] = functionCall;
545 if (
findPath(nestedCall->myId, nestedCall->myArgNr, unsafeValue, invalidValue, callsMap, path, index + 1,
warning)) {
546 path[index] = nestedCall;
556 const std::map<std::string, std::list<const CTU::FileInfo::CallBase *>> &callsMap,
561 std::list<ErrorMessage::FileLocation> locationList;
570 for (
int index = 9; index >= 0; index--) {
578 *functionCallPtr = functionCall;
579 std::copy(functionCall->callValuePath.cbegin(), functionCall->callValuePath.cend(), std::back_inserter(locationList));
582 std::string info_s =
"Calling function " + path[index]->
callFunctionName +
", " + std::to_string(path[index]->callArgNr) +
getOrdinalText(path[index]->callArgNr) +
" argument is " + value1;
584 locationList.push_back(std::move(fileLoc));
589 locationList.push_back(std::move(fileLoc2));
std::vector< const Token * > getArguments(const Token *ftok)
Get arguments (AST)
bool isVariableChanged(const Token *tok, int indirect, const Settings &settings, int depth)
static bool isUnsafeUsage(const Settings &settings, const Token *vartok, MathLib::bigint *value)
std::string toBaseXmlString() const
bool loadBaseFromXml(const tinyxml2::XMLElement *xmlElement)
std::string callFunctionName
std::string callArgumentExpression
bool loadFromXml(const tinyxml2::XMLElement *xmlElement)
ValueFlow::Value::ValueType callValueType
MathLib::bigint callArgValue
std::string toXmlString() const
std::vector< ErrorMessage::FileLocation > callValuePath
std::string toXmlString() const
bool loadFromXml(const tinyxml2::XMLElement *xmlElement)
static std::list< ErrorMessage::FileLocation > getErrorPath(InvalidValueType invalidValue, const UnsafeUsage &unsafeUsage, const std::map< std::string, std::list< const CallBase * >> &callsMap, const char info[], const FunctionCall **const functionCallPtr, bool warning)
std::list< NestedCall > nestedCalls
std::string toString() const override
void loadFromXml(const tinyxml2::XMLElement *xmlElement)
std::list< FunctionCall > functionCalls
std::map< std::string, std::list< const CallBase * > > getCallsMap() const
static std::string toxml(const std::string &str)
Convert XML-sensitive characters into XML entities.
File name and line number.
const Variable * getArgumentVar(nonneg int num) const
nonneg int argCount() const
Function * function
function info for this function
const Token * bodyStart
'{' token
const Token * bodyEnd
'}' token
bool isExecutable() const
This is just a container for general settings so that we don't need to pass individual values to func...
std::list< Scope > scopeList
Information about all namespaces/classes/structures.
const std::string & file(const Token *tok) const
get filename for given token
The token list that the TokenList generates is a linked-list of this class.
static bool Match(const Token *tok, const char pattern[], nonneg int varid=0)
Match given token (or list of tokens) to a pattern list.
static const Token * findmatch(const Token *const startTok, const char pattern[], const nonneg int varId=0)
const ValueType * valueType() const
void astOperand1(Token *tok)
std::string expressionString() const
bool isUnaryOp(const std::string &s) const
void link(Token *linkToToken)
Create link to given token.
void variable(const Variable *v)
Associate this token with given variable.
const std::list< ValueFlow::Value > & values() const
The main purpose is to tokenize the source code.
const Settings & getSettings() const
TokenList list
Token list: stores all tokens.
const SymbolDatabase * getSymbolDatabase() const
enum ValueFlow::Value::ValueType valueType
bool isInconclusive() const
MathLib::bigint typeSize(const Platform &platform, bool p=false) const
Reference reference
Is the outermost indirection of this type a reference or rvalue.
nonneg int pointer
0=>not pointer, 1=>*, 2=>**, 3=>***, etc
Information about a member variable.
bool isArrayOrPointer() const
Is array or pointer variable.
bool isReference() const
Is reference variable.
nonneg int declarationId() const
Get declaration ID (varId used for variable in its declaration).
bool isPointer() const
Is pointer variable.
const ValueType * valueType() const
static constexpr char ATTR_LOC_FILENAME[]
static constexpr char ATTR_INFO[]
static constexpr char ATTR_CALL_ARGVALUE[]
static long long readAttrInt(const tinyxml2::XMLElement *e, const char *attr, bool *error)
static bool findPath(const std::string &callId, nonneg int callArgNr, MathLib::bigint unsafeValue, CTU::FileInfo::InvalidValueType invalidValue, const std::map< std::string, std::list< const CTU::FileInfo::CallBase * >> &callsMap, const CTU::FileInfo::CallBase *path[10], int index, bool warning)
static constexpr char ATTR_CALL_ARGVALUETYPE[]
static constexpr char ATTR_CALL_FUNCNAME[]
static constexpr char ATTR_CALL_ARGNR[]
static constexpr char ATTR_MY_ID[]
static constexpr char ATTR_VALUE[]
static std::string readAttrString(const tinyxml2::XMLElement *e, const char *attr, bool *error)
static constexpr char ATTR_CALL_ARGEXPR[]
static constexpr char ATTR_MY_ARGNAME[]
static constexpr char ATTR_LOC_COLUMN[]
static constexpr char ATTR_MY_ARGNR[]
static int isCallFunction(const Scope *scope, int argnr, const Token *&tok)
static constexpr char ATTR_WARNING[]
static constexpr char ATTR_CALL_ID[]
static std::list< std::pair< const Token *, MathLib::bigint > > getUnsafeFunction(const Settings &settings, const Scope *scope, int argnr, bool(*isUnsafeUsage)(const Settings &settings, const Token *argtok, MathLib::bigint *value))
static constexpr char ATTR_LOC_LINENR[]
std::pair< const Token *, std::string > ErrorPathItem
std::string replaceStr(std::string s, const std::string &from, const std::string &to)
Replace substring.
@ error
Programming error.
Whole program analysis (ctu=Cross Translation Unit)
CPPCHECKLIB std::list< FileInfo::UnsafeUsage > getUnsafeUsage(const Tokenizer &tokenizer, const Settings &settings, bool(*isUnsafeUsage)(const Settings &settings, const Token *argtok, MathLib::bigint *value))
CPPCHECKLIB std::string toString(const std::list< FileInfo::UnsafeUsage > &unsafeUsage)
CPPCHECKLIB std::list< FileInfo::UnsafeUsage > loadUnsafeUsageListFromXml(const tinyxml2::XMLElement *xmlElement)
CPPCHECKLIB std::string getFunctionId(const Tokenizer &tokenizer, const Function *function)
CPPCHECKLIB FileInfo * getFileInfo(const Tokenizer &tokenizer)
Parse current TU and extract file info.
std::string myArgumentName
std::string toString() const
static const char * getOrdinalText(int i)