Skip to content

Commit 6b68c27

Browse files
Fix #13722 Bad varid for volatile bitfield members (danmar#7389)
1 parent 37f4de2 commit 6b68c27

File tree

2 files changed

+37
-10
lines changed

2 files changed

+37
-10
lines changed

lib/tokenize.cpp

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2821,7 +2821,7 @@ static bool scopesMatch(const std::string &scope1, const std::string &scope2, co
28212821
return false;
28222822
}
28232823

2824-
static unsigned int tokDistance(const Token* tok1, const Token* tok2) { // TODO: use index()
2824+
static unsigned int tokDistance(const Token* tok1, const Token* tok2) { // use when index() is not available yet
28252825
unsigned int dist = 0;
28262826
const Token* tok = tok1;
28272827
while (tok != tok2) {
@@ -9924,10 +9924,13 @@ void Tokenizer::simplifyBitfields()
99249924
}
99259925
}
99269926

9927-
if (Token::Match(tok->next(), "const| %type% %name% :") &&
9927+
Token* typeTok = tok->next();
9928+
while (Token::Match(typeTok, "const|volatile"))
9929+
typeTok = typeTok->next();
9930+
if (Token::Match(typeTok, "%type% %name% :") &&
99289931
!Token::Match(tok->next(), "case|public|protected|private|class|struct") &&
99299932
!Token::simpleMatch(tok->tokAt(2), "default :")) {
9930-
Token *tok1 = (tok->strAt(1) == "const") ? tok->tokAt(3) : tok->tokAt(2);
9933+
Token *tok1 = typeTok->next();
99319934
if (Token::Match(tok1, "%name% : %num% [;=]"))
99329935
tok1->setBits(static_cast<unsigned char>(MathLib::toBigNumber(tok1->tokAt(2))));
99339936
if (tok1 && tok1->tokAt(2) &&
@@ -9948,13 +9951,10 @@ void Tokenizer::simplifyBitfields()
99489951
} else {
99499952
tok->next()->deleteNext(2);
99509953
}
9951-
} else if (Token::Match(tok->next(), "const| %type% : %num%|%bool% ;") &&
9952-
tok->strAt(1) != "default") {
9953-
const int offset = (tok->strAt(1) == "const") ? 1 : 0;
9954-
if (!Token::Match(tok->tokAt(3 + offset), "[{};()]")) {
9955-
tok->deleteNext(4 + offset);
9956-
goback = true;
9957-
}
9954+
} else if (Token::Match(typeTok, "%type% : %num%|%bool% ;") &&
9955+
typeTok->str() != "default") {
9956+
tok->deleteNext(4 + tokDistance(tok, typeTok) - 1);
9957+
goback = true;
99589958
}
99599959

99609960
if (last && last->str() == ",") {

test/testtokenize.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,7 @@ class TestTokenizer : public TestFixture {
299299
TEST_CASE(bitfields13); // ticket #3502 (segmentation fault)
300300
TEST_CASE(bitfields15); // ticket #7747 (enum Foo {A,B}:4;)
301301
TEST_CASE(bitfields16); // Save bitfield bit count
302+
TEST_CASE(bitfields17);
302303

303304
TEST_CASE(simplifyNamespaceStd);
304305

@@ -4757,6 +4758,32 @@ class TestTokenizer : public TestFixture {
47574758
ASSERT_EQUALS(1, x->bits());
47584759
}
47594760

4761+
void bitfields17() {
4762+
const char code[] = "struct S {\n" // #13722
4763+
" volatile uint32_t a : 10;\n"
4764+
" volatile uint32_t : 6;\n"
4765+
" volatile uint32_t b : 10;\n"
4766+
" volatile uint32_t : 6;\n"
4767+
"};\n";
4768+
const char expected[] = "struct S {\n"
4769+
"volatile uint32_t a ;\n"
4770+
"\n"
4771+
"volatile uint32_t b ;\n"
4772+
"\n"
4773+
"} ;";
4774+
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
4775+
4776+
const char code2[] = "struct S {\n"
4777+
" const volatile uint32_t a : 10;\n"
4778+
" const volatile uint32_t : 6;\n"
4779+
"};\n";
4780+
const char expected2[] = "struct S {\n"
4781+
"const volatile uint32_t a ;\n"
4782+
"\n"
4783+
"} ;";
4784+
ASSERT_EQUALS(expected2, tokenizeAndStringify(code2));
4785+
}
4786+
47604787
void simplifyNamespaceStd() {
47614788
const char *expected;
47624789

0 commit comments

Comments
 (0)