@@ -45,6 +45,7 @@ static constexpr char ATTR_CALL_ARGNR[] = "call-argnr";
45
45
static constexpr char ATTR_CALL_ARGEXPR[] = " call-argexpr" ;
46
46
static constexpr char ATTR_CALL_ARGVALUETYPE[] = " call-argvaluetype" ;
47
47
static constexpr char ATTR_CALL_ARGVALUE[] = " call-argvalue" ;
48
+ static constexpr char ATTR_CALL_UNKNOWN_FUNCTION_RETURN[] = " call-argvalue-ufr" ;
48
49
static constexpr char ATTR_WARNING[] = " warning" ;
49
50
static constexpr char ATTR_LOC_FILENAME[] = " file" ;
50
51
static constexpr char ATTR_LOC_LINENR[] = " line" ;
@@ -54,6 +55,7 @@ static constexpr char ATTR_MY_ID[] = "my-id";
54
55
static constexpr char ATTR_MY_ARGNR[] = " my-argnr" ;
55
56
static constexpr char ATTR_MY_ARGNAME[] = " my-argname" ;
56
57
static constexpr char ATTR_VALUE[] = " value" ;
58
+ static constexpr char ATTR_UNKNOWN_FUNCTION_RETURN[] = " ufr" ;
57
59
58
60
std::string CTU::getFunctionId (const Tokenizer &tokenizer, const Function *function)
59
61
{
@@ -102,7 +104,8 @@ std::string CTU::FileInfo::FunctionCall::toXmlString() const
102
104
<< toBaseXmlString ()
103
105
<< " " << ATTR_CALL_ARGEXPR << " =\" " << ErrorLogger::toxml (callArgumentExpression) << " \" "
104
106
<< " " << ATTR_CALL_ARGVALUETYPE << " =\" " << static_cast <int >(callValueType) << " \" "
105
- << " " << ATTR_CALL_ARGVALUE << " =\" " << callArgValue << " \" " ;
107
+ << " " << ATTR_CALL_ARGVALUE << " =\" " << callArgValue.value << " \" "
108
+ << " " << ATTR_CALL_UNKNOWN_FUNCTION_RETURN << " =\" " << (int )callArgValue.unknownFunctionReturn << " \" " ;
106
109
if (warning)
107
110
out << " " << ATTR_WARNING << " =\" true\" " ;
108
111
if (callValuePath.empty ())
@@ -141,7 +144,8 @@ std::string CTU::FileInfo::UnsafeUsage::toString() const
141
144
<< " " << ATTR_LOC_FILENAME << " =\" " << ErrorLogger::toxml (location.fileName ) << ' \" '
142
145
<< " " << ATTR_LOC_LINENR << " =\" " << location.lineNumber << ' \" '
143
146
<< " " << ATTR_LOC_COLUMN << " =\" " << location.column << ' \" '
144
- << " " << ATTR_VALUE << " =\" " << value << " \" "
147
+ << " " << ATTR_VALUE << " =\" " << value.value << " \" "
148
+ << " " << ATTR_UNKNOWN_FUNCTION_RETURN << " =\" " << (int )value.unknownFunctionReturn << " \" "
145
149
<< " />\n " ;
146
150
return out.str ();
147
151
}
@@ -201,7 +205,8 @@ bool CTU::FileInfo::FunctionCall::loadFromXml(const tinyxml2::XMLElement *xmlEle
201
205
bool error=false ;
202
206
callArgumentExpression = readAttrString (xmlElement, ATTR_CALL_ARGEXPR, &error);
203
207
callValueType = (ValueFlow::Value::ValueType)readAttrInt (xmlElement, ATTR_CALL_ARGVALUETYPE, &error);
204
- callArgValue = readAttrInt (xmlElement, ATTR_CALL_ARGVALUE, &error);
208
+ callArgValue.value = readAttrInt (xmlElement, ATTR_CALL_ARGVALUE, &error);
209
+ callArgValue.unknownFunctionReturn = readAttrInt (xmlElement, ATTR_CALL_UNKNOWN_FUNCTION_RETURN, &error);
205
210
const char *w = xmlElement->Attribute (ATTR_WARNING);
206
211
warning = w && std::strcmp (w, " true" ) == 0 ;
207
212
for (const tinyxml2::XMLElement *e2 = xmlElement->FirstChildElement (); !error && e2 ; e2 = e2 ->NextSiblingElement ()) {
@@ -267,7 +272,8 @@ std::list<CTU::FileInfo::UnsafeUsage> CTU::loadUnsafeUsageListFromXml(const tiny
267
272
unsafeUsage.location .fileName = readAttrString (e, ATTR_LOC_FILENAME, &error);
268
273
unsafeUsage.location .lineNumber = readAttrInt (e, ATTR_LOC_LINENR, &error);
269
274
unsafeUsage.location .column = readAttrInt (e, ATTR_LOC_COLUMN, &error);
270
- unsafeUsage.value = readAttrInt (e, ATTR_VALUE, &error);
275
+ unsafeUsage.value .value = readAttrInt (e, ATTR_VALUE, &error);
276
+ unsafeUsage.value .unknownFunctionReturn = readAttrInt (e, ATTR_UNKNOWN_FUNCTION_RETURN, &error);
271
277
272
278
if (!error)
273
279
ret.push_back (std::move (unsafeUsage));
@@ -342,7 +348,7 @@ CTU::FileInfo *CTU::getFileInfo(const Tokenizer &tokenizer)
342
348
functionCall.location = FileInfo::Location (tokenizer,tok);
343
349
functionCall.callArgNr = argnr + 1 ;
344
350
functionCall.callArgumentExpression = argtok->expressionString ();
345
- functionCall.callArgValue = value. intvalue ;
351
+ functionCall.callArgValue = value;
346
352
functionCall.warning = !value.errorSeverity ();
347
353
for (const ErrorPathItem &i : value.errorPath ) {
348
354
const std::string& file = tokenizer.list .file (i.first );
@@ -364,7 +370,7 @@ CTU::FileInfo *CTU::getFileInfo(const Tokenizer &tokenizer)
364
370
functionCall.callArgNr = argnr + 1 ;
365
371
functionCall.callArgumentExpression = argtok->expressionString ();
366
372
const auto typeSize = argtok->valueType ()->typeSize (tokenizer.getSettings ().platform );
367
- functionCall.callArgValue = typeSize > 0 ? argtok->variable ()->dimension (0 ) * typeSize : -1 ;
373
+ functionCall.callArgValue . value = typeSize > 0 ? argtok->variable ()->dimension (0 ) * typeSize : -1 ;
368
374
functionCall.warning = false ;
369
375
fileInfo->functionCalls .push_back (std::move (functionCall));
370
376
}
@@ -377,7 +383,7 @@ CTU::FileInfo *CTU::getFileInfo(const Tokenizer &tokenizer)
377
383
functionCall.location = FileInfo::Location (tokenizer, tok);
378
384
functionCall.callArgNr = argnr + 1 ;
379
385
functionCall.callArgumentExpression = argtok->expressionString ();
380
- functionCall.callArgValue = argtok->astOperand1 ()->valueType ()->typeSize (tokenizer.getSettings ().platform );
386
+ functionCall.callArgValue . value = argtok->astOperand1 ()->valueType ()->typeSize (tokenizer.getSettings ().platform );
381
387
functionCall.warning = false ;
382
388
fileInfo->functionCalls .push_back (std::move (functionCall));
383
389
}
@@ -411,7 +417,8 @@ CTU::FileInfo *CTU::getFileInfo(const Tokenizer &tokenizer)
411
417
functionCall.callFunctionName = tok->astOperand1 ()->expressionString ();
412
418
functionCall.location = FileInfo::Location (tokenizer, tok);
413
419
functionCall.callArgNr = argnr + 1 ;
414
- functionCall.callArgValue = 0 ;
420
+ functionCall.callArgValue = v;
421
+ functionCall.callArgValue .value = 0 ;
415
422
functionCall.callArgumentExpression = argtok->expressionString ();
416
423
functionCall.warning = false ;
417
424
fileInfo->functionCalls .push_back (std::move (functionCall));
@@ -436,9 +443,9 @@ CTU::FileInfo *CTU::getFileInfo(const Tokenizer &tokenizer)
436
443
return fileInfo;
437
444
}
438
445
439
- 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))
446
+ static std::vector <std::pair<const Token *, CTU::FileInfo::Value >> getUnsafeFunction (const Settings &settings, const Scope *scope, int argnr, bool (*isUnsafeUsage)(const Settings &settings, const Token *argtok, CTU::FileInfo::Value *value))
440
447
{
441
- std::list <std::pair<const Token *, MathLib::bigint >> ret;
448
+ std::vector <std::pair<const Token *, CTU::FileInfo::Value >> ret;
442
449
const Variable * const argvar = scope->function ->getArgumentVar (argnr);
443
450
if (!argvar->isArrayOrPointer () && !argvar->isReference ())
444
451
return ret;
@@ -459,7 +466,7 @@ static std::list<std::pair<const Token *, MathLib::bigint>> getUnsafeFunction(co
459
466
}
460
467
if (tok2->variable () != argvar)
461
468
continue ;
462
- MathLib::bigint value = 0 ;
469
+ CTU::FileInfo::Value value;
463
470
if (!isUnsafeUsage (settings, tok2, &value))
464
471
return ret; // TODO: Is this a read? then continue..
465
472
ret.emplace_back (tok2, value);
@@ -468,7 +475,7 @@ static std::list<std::pair<const Token *, MathLib::bigint>> getUnsafeFunction(co
468
475
return ret;
469
476
}
470
477
471
- std::list<CTU::FileInfo::UnsafeUsage> CTU::getUnsafeUsage (const Tokenizer &tokenizer, const Settings &settings, bool (*isUnsafeUsage)(const Settings &settings, const Token *argtok, MathLib::bigint *value))
478
+ std::list<CTU::FileInfo::UnsafeUsage> CTU::getUnsafeUsage (const Tokenizer &tokenizer, const Settings &settings, bool (*isUnsafeUsage)(const Settings &settings, const Token *argtok, CTU::FileInfo::Value *value))
472
479
{
473
480
std::list<CTU::FileInfo::UnsafeUsage> unsafeUsage;
474
481
@@ -482,9 +489,9 @@ std::list<CTU::FileInfo::UnsafeUsage> CTU::getUnsafeUsage(const Tokenizer &token
482
489
483
490
// "Unsafe" functions unconditionally reads data before it is written..
484
491
for (int argnr = 0 ; argnr < function->argCount (); ++argnr) {
485
- for (const std::pair<const Token *, MathLib::bigint > &v : getUnsafeFunction (settings, &scope, argnr, isUnsafeUsage)) {
492
+ for (const std::pair<const Token *, CTU::FileInfo::Value > &v : getUnsafeFunction (settings, &scope, argnr, isUnsafeUsage)) {
486
493
const Token *tok = v.first ;
487
- const MathLib::bigint val = v.second ;
494
+ const CTU::FileInfo::Value val = v.second ;
488
495
unsafeUsage.emplace_back (CTU::getFunctionId (tokenizer, function), argnr+1 , tok->str (), CTU::FileInfo::Location (tokenizer,tok), val);
489
496
}
490
497
}
@@ -520,7 +527,7 @@ static bool findPath(const std::string &callId,
520
527
continue ;
521
528
switch (invalidValue) {
522
529
case CTU::FileInfo::InvalidValueType::null:
523
- if (functionCall->callValueType != ValueFlow::Value::ValueType::INT || functionCall->callArgValue != 0 )
530
+ if (functionCall->callValueType != ValueFlow::Value::ValueType::INT || functionCall->callArgValue . value != 0 )
524
531
continue ;
525
532
break ;
526
533
case CTU::FileInfo::InvalidValueType::uninit:
@@ -530,7 +537,7 @@ static bool findPath(const std::string &callId,
530
537
case CTU::FileInfo::InvalidValueType::bufferOverflow:
531
538
if (functionCall->callValueType != ValueFlow::Value::ValueType::BUFFER_SIZE)
532
539
continue ;
533
- if (unsafeValue < 0 || (unsafeValue >= functionCall->callArgValue && functionCall->callArgValue >= 0 ))
540
+ if (unsafeValue < 0 || (unsafeValue >= functionCall->callArgValue . value && functionCall->callArgValue . value >= 0 ))
534
541
break ;
535
542
continue ;
536
543
}
@@ -557,14 +564,20 @@ std::list<ErrorMessage::FileLocation> CTU::FileInfo::getErrorPath(InvalidValueTy
557
564
const char info[],
558
565
const FunctionCall ** const functionCallPtr,
559
566
bool warning,
560
- int maxCtuDepth)
567
+ int maxCtuDepth,
568
+ std::uint8_t *unknownFunctionReturn)
561
569
{
562
- std::list<ErrorMessage::FileLocation> locationList;
563
-
564
570
const CTU::FileInfo::CallBase *path[10 ] = {nullptr };
565
571
566
- if (!findPath (unsafeUsage.myId , unsafeUsage.myArgNr , unsafeUsage.value , invalidValue, callsMap, path, 0 , warning, maxCtuDepth))
567
- return locationList;
572
+ if (!findPath (unsafeUsage.myId , unsafeUsage.myArgNr , unsafeUsage.value .value , invalidValue, callsMap, path, 0 , warning, maxCtuDepth))
573
+ return {};
574
+
575
+ if (unknownFunctionReturn && path[0 ] && dynamic_cast <const CTU::FileInfo::FunctionCall *>(path[0 ])) {
576
+ const auto * v = dynamic_cast <const CTU::FileInfo::FunctionCall *>(path[0 ]);
577
+ *unknownFunctionReturn = v->callArgValue .unknownFunctionReturn ;
578
+ }
579
+
580
+ std::list<ErrorMessage::FileLocation> locationList;
568
581
569
582
const std::string value1 = (invalidValue == InvalidValueType::null) ? " null" : " uninitialized" ;
570
583
0 commit comments