@@ -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 () ? var.nameToken ()->bits () : 0 ;
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,46 @@ 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 {
541+ const size_t charBit = settings.platform .char_bit ;
538542 size_t n = ValueFlow::getSizeOf (vt2, settings,accuracy, ++maxRecursion);
539543 size_t a = getAlignOf (vt2, settings, accuracy);
544+ if (bits > 0 ) {
545+ size_t ret = total;
546+ if (currentBitfieldAlloc == 0 ) {
547+ currentBitfieldAlloc = n;
548+ currentBitCount = 0 ;
549+ } else if (currentBitCount + bits > charBit * currentBitfieldAlloc) {
550+ ret += currentBitfieldAlloc;
551+ currentBitfieldAlloc = n;
552+ currentBitCount = 0 ;
553+ }
554+ currentBitCount += bits;
555+ return ret;
556+ }
540557 if (n == 0 || a == 0 )
541558 return accuracy == Accuracy::ExactOrZero ? 0 : total;
542559 n *= dim;
543560 size_t padding = (a - (total % a)) % a;
561+ if (currentBitCount > 0 ) {
562+ bool fitsInBitfield = currentBitCount + n * charBit <= currentBitfieldAlloc * charBit;
563+ bool isAligned = currentBitCount % (charBit * a) == 0 ;
564+ if (vt2.isIntegral () && fitsInBitfield && isAligned) {
565+ currentBitCount += charBit * n;
566+ return total;
567+ }
568+ n += currentBitfieldAlloc;
569+ currentBitfieldAlloc = 0 ;
570+ currentBitCount = 0 ;
571+ }
544572 return vt.typeScope ->type == ScopeType::eUnion ? std::max (total, n) : total + padding + n;
545573 };
546574 Result result = accumulateStructMembers (vt.typeScope , accHelper, accuracy);
547575 size_t total = result.total ;
576+ if (currentBitCount > 0 )
577+ total += currentBitfieldAlloc;
548578 if (const Type* dt = vt.typeScope ->definedType ) {
549579 total = std::accumulate (dt->derivedFrom .begin (), dt->derivedFrom .end (), total, [&](size_t v, const Type::BaseInfo& bi) {
550580 if (bi.type && bi.type ->classScope )
0 commit comments