Skip to content

Commit 796e812

Browse files
committed
fix
1 parent 8a6c401 commit 796e812

2 files changed

Lines changed: 79 additions & 0 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7789,6 +7789,8 @@ static const Function* getFunction(const Token* tok) {
77897789
return nullptr;
77907790
if (tok->function() && tok->function()->retDef)
77917791
return tok->function();
7792+
if (tok->str() == ")" && tok->link() && Token::simpleMatch(tok->link()->previous(), "_Generic ("))
7793+
return tok->link()->function();
77927794
if (const Variable* lvar = tok->variable()) { // lambda
77937795
const Function* lambda{};
77947796
if (Token::Match(lvar->nameToken()->next(), "; %varid% = [", lvar->declarationId()))
@@ -7842,6 +7844,66 @@ static int getIntegerConstantMacroWidth(const Token* tok) {
78427844
return intnum;
78437845
}
78447846

7847+
void SymbolDatabase::setGenericValueType(Token *par)
7848+
{
7849+
const Token *tok = par->astOperand2();
7850+
std::vector<const Token*> stack;
7851+
7852+
while (tok && tok->str() == ",") {
7853+
stack.push_back(tok);
7854+
tok = tok->astOperand1();
7855+
}
7856+
7857+
if (!tok)
7858+
return;
7859+
7860+
const ValueType *controlVt = tok->valueType();
7861+
7862+
if (!controlVt)
7863+
return;
7864+
7865+
const Token *selected = nullptr;
7866+
7867+
const auto matchVt = [](const ValueType *control, const ValueType *type) {
7868+
// Strip top level qualifiers of controlling expression
7869+
const nonneg int controlMask = ~(1 << control->pointer);
7870+
return control->isTypeEqual(type) &&
7871+
control->sign == type->sign &&
7872+
(control->constness & controlMask) == type->constness &&
7873+
(control->volatileness & controlMask) == type->volatileness;
7874+
};
7875+
7876+
while (!stack.empty()) {
7877+
const Token *comma = stack.back();
7878+
stack.pop_back();
7879+
7880+
const Token *type = comma->next();
7881+
const Token *expr = comma->astOperand2();
7882+
7883+
if (type->str() == "default") {
7884+
if (!selected)
7885+
selected = expr;
7886+
} else {
7887+
ValueType typeVt;
7888+
parsedecl(type, &typeVt, mDefaultSignedness, mSettings);
7889+
7890+
if (matchVt(controlVt, &typeVt)) {
7891+
selected = expr;
7892+
break;
7893+
}
7894+
}
7895+
}
7896+
7897+
if (!selected)
7898+
return;
7899+
7900+
if (selected->valueType())
7901+
setValueType(par, *selected->valueType());
7902+
7903+
if (selected->function())
7904+
par->function(selected->function());
7905+
}
7906+
78457907
void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *tokens)
78467908
{
78477909
if (!tokens)
@@ -7850,7 +7912,18 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
78507912
for (Token *tok = tokens; tok; tok = tok->next())
78517913
tok->setValueType(nullptr);
78527914

7915+
std::vector<Token*> genericClosingParens;
7916+
78537917
for (Token *tok = tokens; tok; tok = tok->next()) {
7918+
if (Token::simpleMatch(tok, "_Generic (")) {
7919+
genericClosingParens.push_back(tok->linkAt(1));
7920+
continue;
7921+
}
7922+
if (!genericClosingParens.empty() && tok == genericClosingParens.back()) {
7923+
setGenericValueType(tok->link());
7924+
genericClosingParens.pop_back();
7925+
continue;
7926+
}
78547927
if (tok->isNumber()) {
78557928
if (MathLib::isFloat(tok->str())) {
78567929
ValueType::Type type = ValueType::Type::DOUBLE;

lib/symboldatabase.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1420,6 +1420,12 @@ class CPPCHECKLIB SymbolDatabase {
14201420
*/
14211421
void validate() const;
14221422

1423+
/**
1424+
* Set value type for generic selection (_Generic).
1425+
* @param par The opening parenthesis of the _Generic expression.
1426+
*/
1427+
void setGenericValueType(Token *par);
1428+
14231429
/** Set valuetype in provided tokenlist */
14241430
void setValueTypeInTokenList(bool reportDebugWarnings, Token *tokens=nullptr);
14251431

0 commit comments

Comments
 (0)