Skip to content

Commit 263ea07

Browse files
committed
handle unnamed bitfields of size zero
1 parent f86bc46 commit 263ea07

File tree

7 files changed

+22
-15
lines changed

7 files changed

+22
-15
lines changed

addons/cppcheckdata.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ class ValueType:
166166
Attributes:
167167
type nonstd/pod/record/smart-pointer/container/iterator/void/bool/char/short/wchar_t/int/long/long long/unknown int/float/double/long double
168168
sign signed/unsigned
169-
bits
169+
bits >= 0 for bit-fields, otherwise -1
170170
pointer
171171
constness
172172
reference
@@ -178,7 +178,7 @@ class ValueType:
178178

179179
type = None
180180
sign = None
181-
bits = 0
181+
bits = -1
182182
constness = 0
183183
pointer = 0
184184
typeScopeId = None
@@ -188,7 +188,7 @@ class ValueType:
188188
def __init__(self, element):
189189
self.type = element.get('valueType-type')
190190
self.sign = element.get('valueType-sign')
191-
self.bits = int(element.get('valueType-bits', 0))
191+
self.bits = int(element.get('valueType-bits', -1))
192192
self.pointer = int(element.get('valueType-pointer', 0))
193193
self.constness = int(element.get('valueType-constness', 0))
194194
self.reference = element.get('valueType-reference')

addons/misra.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2017,7 +2017,7 @@ def misra_6_1(self, data):
20172017
for token in data.tokenlist:
20182018
if not token.valueType:
20192019
continue
2020-
if token.valueType.bits == 0:
2020+
if token.valueType.bits == -1:
20212021
continue
20222022
if not token.variable:
20232023
continue

lib/symboldatabase.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8110,7 +8110,7 @@ std::string ValueType::dump() const
81108110
break;
81118111
}
81128112

8113-
if (bits > 0) {
8113+
if (bits >= 0) {
81148114
ret += " valueType-bits=\"";
81158115
ret += std::to_string(bits);
81168116
ret += '\"';

lib/symboldatabase.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1236,7 +1236,7 @@ class CPPCHECKLIB ValueType {
12361236
DOUBLE,
12371237
LONGDOUBLE
12381238
} type = UNKNOWN_TYPE;
1239-
nonneg int bits{}; ///< bitfield bitcount
1239+
int bits{}; ///< bitfield bitcount
12401240
nonneg int pointer{}; ///< 0=>not pointer, 1=>*, 2=>**, 3=>***, etc
12411241
nonneg int constness{}; ///< bit 0=data, bit 1=*, bit 2=**
12421242
nonneg int volatileness{}; ///< bit 0=data, bit 1=*, bit 2=**

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-
unsigned char mBits{};
85+
char mBits = -1;
8686

8787
// AST..
8888
Token* mAstOperand1{};
@@ -751,9 +751,9 @@ class CPPCHECKLIB Token {
751751

752752
// cppcheck-suppress unusedFunction
753753
bool isBitfield() const {
754-
return mImpl->mBits > 0;
754+
return mImpl->mBits >= 0;
755755
}
756-
unsigned char bits() const {
756+
char bits() const {
757757
return mImpl->mBits;
758758
}
759759
const std::set<TemplateSimplifier::TokenAndName*>* templateSimplifierPointers() const {

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<unsigned char>(MathLib::toBigNumber(tok1->tokAt(2))));
10018+
tok1->setBits(static_cast<char>(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<unsigned char>(newTok->strAt(2) == "true"));
10044+
newTok->setBits(static_cast<char>(newTok->strAt(2) == "true"));
1004510045
else
10046-
newTok->setBits(static_cast<unsigned char>(MathLib::toBigNumber(newTok->tokAt(2))));
10046+
newTok->setBits(static_cast<char>(MathLib::toBigNumber(newTok->tokAt(2))));
1004710047
newTok->deleteNext(2);
1004810048
}
1004910049

lib/valueflow.cpp

Lines changed: 10 additions & 3 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 size_t bits = var.nameToken() ? var.nameToken()->bits() : 0;
443+
const char 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};
@@ -455,7 +455,7 @@ static Result accumulateStructMembers(const Scope* scope, F f, ValueFlow::Accura
455455
else
456456
total = f(total, *vt, dim, bits);
457457
}
458-
if (accuracy == ValueFlow::Accuracy::ExactOrZero && total == 0 && bits == 0)
458+
if (accuracy == ValueFlow::Accuracy::ExactOrZero && total == 0 && bits == -1)
459459
return {0, false};
460460
}
461461
return {total, true};
@@ -537,10 +537,17 @@ 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, size_t bits) -> size_t {
540+
auto accHelper = [&](size_t total, const ValueType& vt2, size_t dim, char 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);
544+
if (bits == 0) {
545+
if (currentBitfieldAlloc == 0) {
546+
bits = n * charBit;
547+
} else {
548+
bits = currentBitfieldAlloc * charBit - currentBitCount;
549+
}
550+
}
544551
if (bits > 0) {
545552
size_t ret = total;
546553
if (currentBitfieldAlloc == 0) {

0 commit comments

Comments
 (0)