@@ -440,6 +440,7 @@ static Result accumulateStructMembers(const Scope* scope, F f, ValueFlow::Accura
440440 for (const Variable& var : scope->varlist ) {
441441 if (var.isStatic ())
442442 continue ;
443+ const size_t bits = var.nameToken ()->bits ();
443444 if (const ValueType* vt = var.valueType ()) {
444445 if (vt->type == ValueType::Type::RECORD && vt->typeScope == scope)
445446 return {0 , false };
@@ -449,12 +450,12 @@ static Result accumulateStructMembers(const Scope* scope, F f, ValueFlow::Accura
449450 if (var.nameToken ()->scope () != scope && var.nameToken ()->scope ()->definedType ) { // anonymous union
450451 const auto ret = anonScopes.insert (var.nameToken ()->scope ());
451452 if (ret.second )
452- total = f (total, *vt, dim);
453+ total = f (total, *vt, dim, bits );
453454 }
454455 else
455- total = f (total, *vt, dim);
456+ total = f (total, *vt, dim, bits );
456457 }
457- if (accuracy == ValueFlow::Accuracy::ExactOrZero && total == 0 )
458+ if (accuracy == ValueFlow::Accuracy::ExactOrZero && total == 0 && bits == 0 )
458459 return {0 , false };
459460 }
460461 return {total, true };
@@ -485,7 +486,7 @@ static size_t getAlignOf(const ValueType& vt, const Settings& settings, ValueFlo
485486 return align == 0 ? 0 : bitCeil (align);
486487 }
487488 if (vt.type == ValueType::Type::RECORD && vt.typeScope ) {
488- auto accHelper = [&](size_t max, const ValueType& vt2, size_t /* dim*/ ) {
489+ auto accHelper = [&](size_t max, const ValueType& vt2, size_t /* dim*/ , size_t /* bits */ ) {
489490 size_t a = getAlignOf (vt2, settings, accuracy, ++maxRecursion);
490491 return std::max (max, a);
491492 };
@@ -534,17 +535,39 @@ size_t ValueFlow::getSizeOf(const ValueType &vt, const Settings &settings, Accur
534535 if (vt.type == ValueType::Type::CONTAINER)
535536 return 3 * settings.platform .sizeof_pointer ; // Just guess
536537 if (vt.type == ValueType::Type::RECORD && vt.typeScope ) {
537- auto accHelper = [&](size_t total, const ValueType& vt2, size_t dim) -> size_t {
538+ size_t currentBitCount = 0 ;
539+ size_t currentBitfieldAlloc = 0 ;
540+ auto accHelper = [&](size_t total, const ValueType& vt2, size_t dim, size_t bits) -> size_t {
538541 size_t n = ValueFlow::getSizeOf (vt2, settings,accuracy, ++maxRecursion);
539542 size_t a = getAlignOf (vt2, settings, accuracy);
543+ if (bits > 0 ) {
544+ size_t ret = total;
545+ if (currentBitfieldAlloc == 0 ) {
546+ currentBitfieldAlloc = n;
547+ currentBitCount = 0 ;
548+ } else if (currentBitCount + bits > 8 * currentBitfieldAlloc) {
549+ ret += currentBitfieldAlloc;
550+ currentBitfieldAlloc = n;
551+ currentBitCount = 0 ;
552+ }
553+ currentBitCount += bits;
554+ return ret;
555+ }
540556 if (n == 0 || a == 0 )
541557 return accuracy == Accuracy::ExactOrZero ? 0 : total;
542558 n *= dim;
543559 size_t padding = (a - (total % a)) % a;
560+ if (currentBitCount > 0 ) {
561+ n += currentBitfieldAlloc;
562+ currentBitfieldAlloc = 0 ;
563+ currentBitCount = 0 ;
564+ }
544565 return vt.typeScope ->type == ScopeType::eUnion ? std::max (total, n) : total + padding + n;
545566 };
546567 Result result = accumulateStructMembers (vt.typeScope , accHelper, accuracy);
547568 size_t total = result.total ;
569+ if (currentBitCount > 0 )
570+ total += currentBitfieldAlloc;
548571 if (const Type* dt = vt.typeScope ->definedType ) {
549572 total = std::accumulate (dt->derivedFrom .begin (), dt->derivedFrom .end (), total, [&](size_t v, const Type::BaseInfo& bi) {
550573 if (bi.type && bi.type ->classScope )
0 commit comments