Skip to content

Commit 7ab4ae7

Browse files
authored
Fix #12813 (Tokenizer: handle alignas in C11 code) (#6487)
1 parent b84bc8d commit 7ab4ae7

File tree

2 files changed

+43
-18
lines changed

2 files changed

+43
-18
lines changed

lib/tokenize.cpp

+32-18
Original file line numberDiff line numberDiff line change
@@ -9299,7 +9299,11 @@ void Tokenizer::simplifyCppcheckAttribute()
92999299

93009300
void Tokenizer::simplifyCPPAttribute()
93019301
{
9302-
if ((isCPP() && mSettings.standards.cpp < Standards::CPP11) || (isC() && mSettings.standards.c < Standards::C23))
9302+
// According to cppreference alignas is a c21 feature however the macro is often available when compiling c11
9303+
const bool hasAlignas = ((isCPP() && mSettings.standards.cpp >= Standards::CPP11) || (isC() && mSettings.standards.c >= Standards::C11));
9304+
const bool hasCppAttribute = ((isCPP() && mSettings.standards.cpp >= Standards::CPP11) || (isC() && mSettings.standards.c >= Standards::C23));
9305+
9306+
if (!hasAlignas && !hasCppAttribute)
93039307
return;
93049308

93059309
for (Token *tok = list.front(); tok;) {
@@ -9308,6 +9312,10 @@ void Tokenizer::simplifyCPPAttribute()
93089312
continue;
93099313
}
93109314
if (isCPPAttribute(tok)) {
9315+
if (!hasCppAttribute) {
9316+
tok = skipCPPOrAlignAttribute(tok)->next();
9317+
continue;
9318+
}
93119319
if (Token::findsimplematch(tok->tokAt(2), "noreturn", tok->link())) {
93129320
Token * head = skipCPPOrAlignAttribute(tok)->next();
93139321
while (isCPPAttribute(head) || isAlignAttribute(head))
@@ -9359,23 +9367,29 @@ void Tokenizer::simplifyCPPAttribute()
93599367
}
93609368
}
93619369
} else {
9362-
if (Token::simpleMatch(tok, "alignas (")) {
9363-
Token* atok = nullptr;
9364-
if (Token::Match(tok->previous(), "%name%"))
9365-
atok = tok->previous();
9366-
else {
9367-
atok = tok;
9368-
while (isCPPAttribute(atok) || isAlignAttribute(atok))
9369-
atok = skipCPPOrAlignAttribute(atok)->next();
9370-
}
9371-
if (atok) {
9372-
std::string a;
9373-
for (const Token* t = tok->tokAt(2); t && t->str() != ")"; t = t->next())
9374-
a += " " + t->str();
9375-
if (a.size() > 1)
9376-
atok->addAttributeAlignas(a.substr(1));
9377-
}
9378-
// alignment requirements could be checked here
9370+
// alignas(expr)
9371+
9372+
if (!hasAlignas) {
9373+
tok = skipCPPOrAlignAttribute(tok)->next();
9374+
continue;
9375+
}
9376+
9377+
// alignment requirements could be checked here
9378+
9379+
Token* atok = nullptr;
9380+
if (Token::Match(tok->previous(), "%name%"))
9381+
atok = tok->previous();
9382+
else {
9383+
atok = tok;
9384+
while (isCPPAttribute(atok) || isAlignAttribute(atok))
9385+
atok = skipCPPOrAlignAttribute(atok)->next();
9386+
}
9387+
if (atok) {
9388+
std::string a;
9389+
for (const Token* t = tok->tokAt(2); t && t->str() != ")"; t = t->next())
9390+
a += " " + t->str();
9391+
if (a.size() > 1)
9392+
atok->addAttributeAlignas(a.substr(1));
93799393
}
93809394
}
93819395
Token::eraseTokens(tok, skipCPPOrAlignAttribute(tok)->next());

test/testtokenize.cpp

+11
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,7 @@ class TestTokenizer : public TestFixture {
439439

440440
TEST_CASE(removeAlignas1);
441441
TEST_CASE(removeAlignas2); // Do not remove alignof in the same way
442+
TEST_CASE(removeAlignas3); // remove alignas in C11 code
442443
TEST_CASE(dumpAlignas);
443444

444445
TEST_CASE(simplifyCoroutines);
@@ -7851,6 +7852,16 @@ class TestTokenizer : public TestFixture {
78517852
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
78527853
}
78537854

7855+
void removeAlignas3() {
7856+
const char code[] = "alignas(16) int x;";
7857+
const char expected[] = "int x ;";
7858+
// According to cppreference alignas() is a C23 macro; but it is often available when compiling C11.
7859+
// Misra C has C11 examples with alignas.
7860+
// Microsoft provides alignas in C11.
7861+
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Platform::Type::Native, false, Standards::CPP11, Standards::C11));
7862+
ASSERT_EQUALS(expected, tokenizeAndStringify(code, true, Platform::Type::Native, true, Standards::CPP11, Standards::C11));
7863+
}
7864+
78547865
void dumpAlignas() {
78557866
Settings settings;
78567867
SimpleTokenizer tokenizer(settings, *this);

0 commit comments

Comments
 (0)