Skip to content

Commit d38f223

Browse files
committed
use short for bit count, print error on larger values
1 parent 401575e commit d38f223

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

lib/token.h

Lines changed: 10 additions & 4 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-
MathLib::bigint mBits = -1;
85+
short 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-
MathLib::bigint bits() const {
756+
short bits() const {
757757
return mImpl->mBits;
758758
}
759759
const std::set<TemplateSimplifier::TokenAndName*>* templateSimplifierPointers() const {
@@ -767,8 +767,14 @@ class CPPCHECKLIB Token {
767767
mImpl->mTemplateSimplifierPointers = new std::set<TemplateSimplifier::TokenAndName*>;
768768
mImpl->mTemplateSimplifierPointers->insert(tokenAndName);
769769
}
770-
void setBits(const MathLib::bigint b) {
771-
mImpl->mBits = b;
770+
bool setBits(const MathLib::bigint b) {
771+
const MathLib::bigint max = std::numeric_limits<short>::max();
772+
if (b > max) {
773+
mImpl->mBits = max;
774+
return false;
775+
}
776+
mImpl->mBits = b < 0 ? -1 : b;
777+
return true;
772778
}
773779

774780
bool isUtf8() const {

lib/tokenize.cpp

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10007,6 +10007,14 @@ void Tokenizer::simplifyBitfields()
1000710007
}
1000810008
}
1000910009

10010+
const auto tooLargeError = [this](const Token *tok) {
10011+
const MathLib::bigint max = std::numeric_limits<short>::max();
10012+
reportError(tok,
10013+
Severity::warning,
10014+
"tooLargeBitField",
10015+
"Bit-field size exceeds max number of bits " + std::to_string(max));
10016+
};
10017+
1001010018
Token* typeTok = tok->next();
1001110019
while (Token::Match(typeTok, "const|volatile"))
1001210020
typeTok = typeTok->next();
@@ -10015,7 +10023,8 @@ void Tokenizer::simplifyBitfields()
1001510023
!Token::simpleMatch(tok->tokAt(2), "default :")) {
1001610024
Token *tok1 = typeTok->next();
1001710025
if (Token::Match(tok1, "%name% : %num% [;=]"))
10018-
tok1->setBits(MathLib::toBigNumber(tok1->tokAt(2)));
10026+
if (!tok1->setBits(MathLib::toBigNumber(tok1->tokAt(2))))
10027+
tooLargeError(tok1->tokAt(2));
1001910028
if (tok1 && tok1->tokAt(2) &&
1002010029
(Token::Match(tok1->tokAt(2), "%bool%|%num%") ||
1002110030
!Token::Match(tok1->tokAt(2), "public|protected|private| %type% ::|<|,|{|;"))) {
@@ -10040,10 +10049,13 @@ void Tokenizer::simplifyBitfields()
1004010049
const std::string name = "anonymous@" + std::to_string(id);
1004110050
Token *newTok = typeTok->insertToken(name);
1004210051
newTok->isAnonymous(true);
10052+
bool failed;
1004310053
if (newTok->tokAt(2)->isBoolean())
10044-
newTok->setBits(newTok->strAt(2) == "true");
10054+
failed = !newTok->setBits(newTok->strAt(2) == "true");
1004510055
else
10046-
newTok->setBits(MathLib::toBigNumber(newTok->tokAt(2)));
10056+
failed = !newTok->setBits(MathLib::toBigNumber(newTok->tokAt(2)));
10057+
if (failed)
10058+
tooLargeError(newTok->tokAt(2));
1004710059
newTok->deleteNext(2);
1004810060
}
1004910061

0 commit comments

Comments
 (0)