Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #12807 (dump file: provide alignas expressions) #6483

Merged
merged 3 commits into from
Jun 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions lib/token.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,15 @@ struct TokenImpl {
};
CppcheckAttributes* mCppcheckAttributes{};

// alignas expressions
std::unique_ptr<std::vector<std::string>> mAttributeAlignas;
void addAttributeAlignas(const std::string& a) {
if (!mAttributeAlignas)
mAttributeAlignas = std::unique_ptr<std::vector<std::string>>(new std::vector<std::string>());
if (std::find(mAttributeAlignas->cbegin(), mAttributeAlignas->cend(), a) == mAttributeAlignas->cend())
mAttributeAlignas->push_back(a);
}

// For memoization, to speed up parsing of huge arrays #8897
enum class Cpp11init { UNKNOWN, CPP11INIT, NOINIT } mCpp11init = Cpp11init::UNKNOWN;

Expand Down Expand Up @@ -545,6 +554,15 @@ class CPPCHECKLIB Token {
void isAttributeMaybeUnused(const bool value) {
setFlag(fIsAttributeMaybeUnused, value);
}
std::vector<std::string> getAttributeAlignas() const {
return mImpl->mAttributeAlignas ? *mImpl->mAttributeAlignas : std::vector<std::string>();
}
bool hasAttributeAlignas() const {
return !!mImpl->mAttributeAlignas;
}
void addAttributeAlignas(const std::string& a) {
mImpl->addAttributeAlignas(a);
}
void setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, MathLib::bigint value) {
mImpl->setCppcheckAttribute(type, value);
}
Expand Down
22 changes: 22 additions & 0 deletions lib/tokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6044,6 +6044,13 @@ void Tokenizer::dump(std::ostream &out) const
outs += " isAttributeMaybeUnused=\"true\"";
if (tok->isAttributeUnused())
outs += " isAttributeUnused=\"true\"";
if (tok->hasAttributeAlignas()) {
const std::vector<std::string>& a = tok->getAttributeAlignas();
outs += " alignas=\"" + ErrorLogger::toxml(a[0]) + "\"";
if (a.size() > 1)
// we could write all alignas expressions but currently we only need 2
outs += " alignas2=\"" + ErrorLogger::toxml(a[1]) + "\"";
}
if (tok->link()) {
outs += " link=\"";
outs += id_string(tok->link());
Expand Down Expand Up @@ -9353,6 +9360,21 @@ void Tokenizer::simplifyCPPAttribute()
}
} else {
if (Token::simpleMatch(tok, "alignas (")) {
Token* atok = nullptr;
if (Token::Match(tok->previous(), "%name%"))
atok = tok->previous();
else {
atok = tok;
while (isCPPAttribute(atok) || isAlignAttribute(atok))
atok = skipCPPOrAlignAttribute(atok)->next();
}
if (atok) {
std::string a;
for (const Token* t = tok->tokAt(2); t && t->str() != ")"; t = t->next())
a += " " + t->str();
if (a.size() > 1)
atok->addAttributeAlignas(a.substr(1));
}
// alignment requirements could be checked here
}
}
Expand Down
12 changes: 12 additions & 0 deletions test/testtokenize.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,7 @@ class TestTokenizer : public TestFixture {

TEST_CASE(removeAlignas1);
TEST_CASE(removeAlignas2); // Do not remove alignof in the same way
TEST_CASE(dumpAlignas);

TEST_CASE(simplifyCoroutines);

Expand Down Expand Up @@ -7850,6 +7851,17 @@ class TestTokenizer : public TestFixture {
ASSERT_EQUALS(expected, tokenizeAndStringify(code));
}

void dumpAlignas() {
Settings settings;
SimpleTokenizer tokenizer(settings, *this);
tokenizer.tokenize("int alignas(8) alignas(16) x;", false);
ASSERT(Token::simpleMatch(tokenizer.tokens(), "int x ;"));
std::ostringstream ostr;
tokenizer.dump(ostr);
const std::string dump = ostr.str();
ASSERT(dump.find(" alignas=\"8\" alignas2=\"16\"") != std::string::npos);
}

void simplifyCoroutines() {
const Settings settings = settingsBuilder().cpp(Standards::CPP20).build();

Expand Down
Loading