@@ -426,7 +426,7 @@ void ValueFlow::combineValueProperties(const ValueFlow::Value &value1, const Val
426426
427427
428428template <class F >
429- static size_t accumulateStructMembers (const Scope* scope, F f)
429+ static size_t accumulateStructMembers (const Scope* scope, F f, ValueFlow::Accuracy accuracy )
430430{
431431 size_t total = 0 ;
432432 std::set<const Scope*> anonScopes;
@@ -447,7 +447,7 @@ static size_t accumulateStructMembers(const Scope* scope, F f)
447447 else
448448 total = f (total, *vt, dim);
449449 }
450- if (total == 0 )
450+ if (accuracy == ValueFlow::Accuracy::ExcactOrZero && total == 0 )
451451 return 0 ;
452452 }
453453 return total;
@@ -467,37 +467,37 @@ static size_t bitCeil(size_t x)
467467 return x + 1 ;
468468}
469469
470- static size_t getAlignOf (const ValueType& vt, const Settings& settings, int maxRecursion = 0 )
470+ static size_t getAlignOf (const ValueType& vt, const Settings& settings, ValueFlow::Accuracy accuracy, int maxRecursion = 0 )
471471{
472472 if (maxRecursion == settings.vfOptions .maxAlignOfRecursion ) {
473473 // TODO: add bailout message
474474 return 0 ;
475475 }
476476 if (vt.pointer || vt.reference != Reference::None || vt.isPrimitive ()) {
477- auto align = ValueFlow::getSizeOf (vt, settings);
477+ auto align = ValueFlow::getSizeOf (vt, settings, accuracy );
478478 return align == 0 ? 0 : bitCeil (align);
479479 }
480480 if (vt.type == ValueType::Type::RECORD && vt.typeScope ) {
481481 auto accHelper = [&](size_t max, const ValueType& vt2, size_t /* dim*/ ) {
482- size_t a = getAlignOf (vt2, settings, ++maxRecursion);
482+ size_t a = getAlignOf (vt2, settings, accuracy, ++maxRecursion);
483483 return std::max (max, a);
484484 };
485485 size_t total = 0 ;
486486 if (const Type* dt = vt.typeScope ->definedType ) {
487487 total = std::accumulate (dt->derivedFrom .begin (), dt->derivedFrom .end (), total, [&](size_t v, const Type::BaseInfo& bi) {
488488 if (bi.type && bi.type ->classScope )
489- v += accumulateStructMembers (bi.type ->classScope , accHelper);
489+ v += accumulateStructMembers (bi.type ->classScope , accHelper, accuracy );
490490 return v;
491491 });
492492 }
493- return total + accumulateStructMembers (vt.typeScope , accHelper);
493+ return total + accumulateStructMembers (vt.typeScope , accHelper, accuracy );
494494 }
495495 if (vt.type == ValueType::Type::CONTAINER)
496496 return settings.platform .sizeof_pointer ; // Just guess
497497 return 0 ;
498498}
499499
500- size_t ValueFlow::getSizeOf (const ValueType &vt, const Settings &settings, int maxRecursion)
500+ size_t ValueFlow::getSizeOf (const ValueType &vt, const Settings &settings, Accuracy accuracy, int maxRecursion)
501501{
502502 if (maxRecursion == settings.vfOptions .maxSizeOfRecursion ) {
503503 // TODO: add bailout message
@@ -527,27 +527,28 @@ size_t ValueFlow::getSizeOf(const ValueType &vt, const Settings &settings, int m
527527 return 3 * settings.platform .sizeof_pointer ; // Just guess
528528 if (vt.type == ValueType::Type::RECORD && vt.typeScope ) {
529529 auto accHelper = [&](size_t total, const ValueType& vt2, size_t dim) -> size_t {
530- size_t n = ValueFlow::getSizeOf (vt2, settings, ++maxRecursion);
531- size_t a = getAlignOf (vt2, settings);
530+ size_t n = ValueFlow::getSizeOf (vt2, settings,accuracy, ++maxRecursion);
531+ size_t a = getAlignOf (vt2, settings, accuracy );
532532 if (n == 0 || a == 0 )
533- return 0 ;
533+ return accuracy == Accuracy::ExcactOrZero ? 0 : total ;
534534 n *= dim;
535535 size_t padding = (a - (total % a)) % a;
536536 return vt.typeScope ->type == ScopeType::eUnion ? std::max (total, n) : total + padding + n;
537537 };
538- size_t total = accumulateStructMembers (vt.typeScope , accHelper);
538+ size_t total = accumulateStructMembers (vt.typeScope , accHelper, accuracy );
539539 if (const Type* dt = vt.typeScope ->definedType ) {
540540 total = std::accumulate (dt->derivedFrom .begin (), dt->derivedFrom .end (), total, [&](size_t v, const Type::BaseInfo& bi) {
541541 if (bi.type && bi.type ->classScope )
542- v += accumulateStructMembers (bi.type ->classScope , accHelper);
542+ v += accumulateStructMembers (bi.type ->classScope , accHelper, accuracy );
543543 return v;
544544 });
545545 }
546- if (total == 0 )
546+ if (accuracy == Accuracy::ExcactOrZero && total == 0 )
547547 return 0 ;
548- size_t align = getAlignOf (vt, settings);
548+ total = std::max (size_t {1 }, total);
549+ size_t align = getAlignOf (vt, settings, accuracy);
549550 if (align == 0 )
550- return 0 ;
551+ return accuracy == Accuracy::ExcactOrZero ? 0 : total ;
551552 total += (align - (total % align)) % align;
552553 return total;
553554 }
@@ -3614,8 +3615,8 @@ static bool isTruncated(const ValueType* src, const ValueType* dst, const Settin
36143615 if (src->smartPointer && dst->smartPointer )
36153616 return false ;
36163617 if ((src->isIntegral () && dst->isIntegral ()) || (src->isFloat () && dst->isFloat ())) {
3617- const size_t srcSize = ValueFlow::getSizeOf (*src, settings);
3618- const size_t dstSize = ValueFlow::getSizeOf (*dst, settings);
3618+ const size_t srcSize = ValueFlow::getSizeOf (*src, settings, ValueFlow::Accuracy::LowerBound );
3619+ const size_t dstSize = ValueFlow::getSizeOf (*dst, settings, ValueFlow::Accuracy::LowerBound );
36193620 if (srcSize > dstSize)
36203621 return true ;
36213622 if (srcSize == dstSize && src->sign != dst->sign )
@@ -4138,10 +4139,10 @@ static std::list<ValueFlow::Value> truncateValues(std::list<ValueFlow::Value> va
41384139 if (!dst || !dst->isIntegral ())
41394140 return values;
41404141
4141- const size_t sz = ValueFlow::getSizeOf (*dst, settings);
4142+ const size_t sz = ValueFlow::getSizeOf (*dst, settings, ValueFlow::Accuracy::ExcactOrZero );
41424143
41434144 if (src) {
4144- const size_t osz = ValueFlow::getSizeOf (*src, settings);
4145+ const size_t osz = ValueFlow::getSizeOf (*src, settings, ValueFlow::Accuracy::ExcactOrZero );
41454146 if (osz >= sz && dst->sign == ValueType::Sign::SIGNED && src->sign == ValueType::Sign::UNSIGNED) {
41464147 values.remove_if ([&](const ValueFlow::Value& value) {
41474148 if (!value.isIntValue ())
0 commit comments