Skip to content

Commit c648c5f

Browse files
committed
account for bit-fields with greater number of bits than its type
1 parent a20ab69 commit c648c5f

3 files changed

Lines changed: 12 additions & 8 deletions

File tree

lib/token.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ struct TokenImpl {
8282
nonneg int mIndex{};
8383

8484
/** Bitfield bit count. */
85-
char mBits = -1;
85+
MathLib::bigint mBits = -1;
8686

8787
// AST..
8888
Token* mAstOperand1{};
@@ -753,7 +753,7 @@ class CPPCHECKLIB Token {
753753
bool isBitfield() const {
754754
return mImpl->mBits >= 0;
755755
}
756-
char bits() const {
756+
MathLib::bigint bits() const {
757757
return mImpl->mBits;
758758
}
759759
const std::set<TemplateSimplifier::TokenAndName*>* templateSimplifierPointers() const {
@@ -767,7 +767,7 @@ class CPPCHECKLIB Token {
767767
mImpl->mTemplateSimplifierPointers = new std::set<TemplateSimplifier::TokenAndName*>;
768768
mImpl->mTemplateSimplifierPointers->insert(tokenAndName);
769769
}
770-
void setBits(const unsigned char b) {
770+
void setBits(const MathLib::bigint b) {
771771
mImpl->mBits = b;
772772
}
773773

lib/tokenize.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10015,7 +10015,7 @@ void Tokenizer::simplifyBitfields()
1001510015
!Token::simpleMatch(tok->tokAt(2), "default :")) {
1001610016
Token *tok1 = typeTok->next();
1001710017
if (Token::Match(tok1, "%name% : %num% [;=]"))
10018-
tok1->setBits(static_cast<char>(MathLib::toBigNumber(tok1->tokAt(2))));
10018+
tok1->setBits(MathLib::toBigNumber(tok1->tokAt(2)));
1001910019
if (tok1 && tok1->tokAt(2) &&
1002010020
(Token::Match(tok1->tokAt(2), "%bool%|%num%") ||
1002110021
!Token::Match(tok1->tokAt(2), "public|protected|private| %type% ::|<|,|{|;"))) {
@@ -10041,9 +10041,9 @@ void Tokenizer::simplifyBitfields()
1004110041
Token *newTok = typeTok->insertToken(name);
1004210042
newTok->isAnonymousBitfield(true);
1004310043
if (newTok->tokAt(2)->isBoolean())
10044-
newTok->setBits(static_cast<char>(newTok->strAt(2) == "true"));
10044+
newTok->setBits(newTok->strAt(2) == "true");
1004510045
else
10046-
newTok->setBits(static_cast<char>(MathLib::toBigNumber(newTok->tokAt(2))));
10046+
newTok->setBits(MathLib::toBigNumber(newTok->tokAt(2)));
1004710047
newTok->deleteNext(2);
1004810048
}
1004910049

lib/valueflow.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -440,7 +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 char bits = var.nameToken() ? var.nameToken()->bits() : -1;
443+
const MathLib::bigint bits = var.nameToken() ? var.nameToken()->bits() : -1;
444444
if (const ValueType* vt = var.valueType()) {
445445
if (vt->type == ValueType::Type::RECORD && vt->typeScope == scope)
446446
return {0, false};
@@ -537,7 +537,7 @@ size_t ValueFlow::getSizeOf(const ValueType &vt, const Settings &settings, Accur
537537
if (vt.type == ValueType::Type::RECORD && vt.typeScope) {
538538
size_t currentBitCount = 0;
539539
size_t currentBitfieldAlloc = 0;
540-
auto accHelper = [&](size_t total, const ValueType& vt2, size_t dim, char bits) -> size_t {
540+
auto accHelper = [&](size_t total, const ValueType& vt2, size_t dim, MathLib::bigint bits) -> size_t {
541541
const size_t charBit = settings.platform.char_bit;
542542
size_t n = ValueFlow::getSizeOf(vt2, settings,accuracy, ++maxRecursion);
543543
size_t a = getAlignOf(vt2, settings, accuracy);
@@ -558,6 +558,10 @@ size_t ValueFlow::getSizeOf(const ValueType &vt, const Settings &settings, Accur
558558
currentBitfieldAlloc = n;
559559
currentBitCount = 0;
560560
}
561+
while (bits > charBit * currentBitfieldAlloc) {
562+
ret += currentBitfieldAlloc;
563+
bits -= charBit * currentBitfieldAlloc;
564+
}
561565
currentBitCount += bits;
562566
return ret;
563567
}

0 commit comments

Comments
 (0)