diff --git a/lib/token.h b/lib/token.h index 2f054d969468..f7da22a4b98a 100644 --- a/lib/token.h +++ b/lib/token.h @@ -122,6 +122,9 @@ struct TokenImpl { }; CppcheckAttributes* mCppcheckAttributes{}; + // alignas expressions + std::string mAttributeAlignas; + // For memoization, to speed up parsing of huge arrays #8897 enum class Cpp11init { UNKNOWN, CPP11INIT, NOINIT } mCpp11init = Cpp11init::UNKNOWN; @@ -545,6 +548,19 @@ class CPPCHECKLIB Token { void isAttributeMaybeUnused(const bool value) { setFlag(fIsAttributeMaybeUnused, value); } + std::string getAttributeAlignas() const { + return mImpl->mAttributeAlignas; + } + bool hasAttributeAlignas() const { + return !mImpl->mAttributeAlignas.empty(); + } + void setAttributeAlignas(const std::string& a) { + if (a.empty() || mImpl->mAttributeAlignas.empty()) + mImpl->mAttributeAlignas = a; + else if (a != mImpl->mAttributeAlignas) + // mismatching alignas expressions, add both + mImpl->mAttributeAlignas += "\\" + a; + } void setCppcheckAttribute(TokenImpl::CppcheckAttributes::Type type, MathLib::bigint value) { mImpl->setCppcheckAttribute(type, value); } diff --git a/lib/tokenize.cpp b/lib/tokenize.cpp index 2ca6189c2058..453f441f3e36 100644 --- a/lib/tokenize.cpp +++ b/lib/tokenize.cpp @@ -6044,6 +6044,8 @@ void Tokenizer::dump(std::ostream &out) const outs += " isAttributeMaybeUnused=\"true\""; if (tok->isAttributeUnused()) outs += " isAttributeUnused=\"true\""; + if (tok->hasAttributeAlignas()) + outs += " alignas=\"" + ErrorLogger::toxml(tok->getAttributeAlignas()) + "\""; if (tok->link()) { outs += " link=\""; outs += id_string(tok->link()); @@ -9353,6 +9355,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->setAttributeAlignas(a.substr(1)); + } // alignment requirements could be checked here } }