Skip to content

Commit

Permalink
#12400: dump file: Add volatileness to ValueType
Browse files Browse the repository at this point in the history
  • Loading branch information
swasti16 committed Feb 10, 2024
1 parent 503c109 commit 9a833de
Show file tree
Hide file tree
Showing 3 changed files with 129 additions and 4 deletions.
81 changes: 77 additions & 4 deletions lib/symboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2437,6 +2437,7 @@ void Variable::setValueType(const ValueType &valueType)
if ((mValueType->pointer > 0) && (!isArray() || Token::Match(mNameToken->previous(), "( * %name% )")))
setFlag(fIsPointer, true);
setFlag(fIsConst, mValueType->constness & (1U << mValueType->pointer));
setFlag(fIsVolatile, mValueType->volatileness & (1U << mValueType->pointer));
if (mValueType->smartPointerType)
setFlag(fIsSmartPointer, true);
}
Expand Down Expand Up @@ -4354,6 +4355,10 @@ void SymbolDatabase::printXml(std::ostream &out) const
outs += " constness=\"";
outs += std::to_string(var->valueType()->constness);
outs += '\"';

outs += " volatileness=\"";
outs += std::to_string(var->valueType()->volatileness);
outs += '\"';
}
outs += " isArray=\"";
outs += bool_to_string(var->isArray());
Expand Down Expand Up @@ -5608,7 +5613,8 @@ static bool hasMatchingConstructor(const Scope* classScope, const ValueType* arg
vt->type == argType->type &&
(argType->sign == ValueType::Sign::UNKNOWN_SIGN || vt->sign == argType->sign) &&
vt->pointer == argType->pointer &&
(vt->constness & 1) >= (argType->constness & 1);
(vt->constness & 1) >= (argType->constness & 1) &&
(vt->volatileness & 1) >= (argType->volatileness & 1);
});
}

Expand Down Expand Up @@ -5717,6 +5723,8 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
{
if (typeToken->str() == "const")
ret.constness |= (1 << ret.pointer);
else if (typeToken->str() == "volatile")
ret.volatileness |= (1 << ret.pointer);
else if (typeToken->str() == "*")
ret.pointer++;
else if (typeToken->str() == "<") {
Expand Down Expand Up @@ -6454,6 +6462,8 @@ void SymbolDatabase::setValueType(Token* tok, const Variable& var, SourceLocatio
const ValueType * const vt = tok->astOperand1()->valueType();
if (vt && (vt->constness & 1) != 0)
valuetype.constness |= 1;
if (vt && (vt->volatileness & 1) != 0)
valuetype.volatileness |= 1;
}
setValueType(tok, valuetype);
}
Expand Down Expand Up @@ -6549,6 +6559,8 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
if (parsedecl(vt1->containerTypeToken, &item, mDefaultSignedness, mSettings, mIsCpp)) {
if (item.constness == 0)
item.constness = vt1->constness;
if (item.volatileness == 0)
item.volatileness = vt1->volatileness;
if (isContainerYieldPointer(vt1->container->getYield(parent->next()->str())))
item.pointer += 1;
else
Expand Down Expand Up @@ -6583,10 +6595,14 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
ValueType vt(*vt2);
if (vt.constness & (1 << vt.pointer))
vt.constness &= ~(1 << vt.pointer);
if (vt.volatileness & (1 << vt.pointer))
vt.volatileness &= ~(1 << vt.pointer);
if (autoTok->strAt(1) == "*" && vt.pointer)
vt.pointer--;
if (Token::Match(autoTok->tokAt(-1), "const|constexpr"))
vt.constness |= (1 << vt.pointer);
if (Token::simpleMatch(autoTok->tokAt(-1), "volatile"))
vt.volatileness |= (1 << vt.pointer);
setValueType(autoTok, vt);
setAutoTokenProperties(autoTok);
if (vt2->pointer > vt.pointer)
Expand All @@ -6601,10 +6617,16 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
vt2_.pointer = 1;
if ((vt.constness & (1 << vt2->pointer)) != 0)
vt2_.constness |= (1 << vt2->pointer);
if (!Token::Match(autoTok->tokAt(1), "*|&"))
if ((vt.volatileness & (1 << vt2->pointer)) != 0)
vt2_.volatileness |= (1 << vt2->pointer);
if (!Token::Match(autoTok->tokAt(1), "*|&")) {
vt2_.constness = vt.constness;
vt2_.volatileness = vt.volatileness;
}
if (Token::simpleMatch(autoTok->tokAt(1), "* const"))
vt2_.constness |= (1 << vt2->pointer);
if (Token::simpleMatch(autoTok->tokAt(1), "* volatile"))
vt2_.volatileness |= (1 << vt2->pointer);
var->setValueType(vt2_);
if (vt2->typeScope && vt2->typeScope->definedType) {
var->type(vt2->typeScope->definedType);
Expand Down Expand Up @@ -6655,6 +6677,8 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
if (parsedecl(valuetype.containerTypeToken, &vt, mDefaultSignedness, mSettings, mIsCpp)) {
if (vt.constness == 0)
vt.constness = valuetype.constness;
if (vt.volatileness == 0)
vt.volatileness = valuetype.volatileness;
vt.reference = Reference::LValue;
setValueType(parent, vt);
return;
Expand All @@ -6667,6 +6691,8 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
if (parsedecl(valuetype.smartPointerTypeToken, &vt, mDefaultSignedness, mSettings, mIsCpp)) {
if (vt.constness == 0)
vt.constness = valuetype.constness;
if (vt.volatileness == 0)
vt.volatileness = valuetype.volatileness;
setValueType(parent, vt);
return;
}
Expand Down Expand Up @@ -6729,11 +6755,13 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
!parent->previous()->valueType() &&
Token::simpleMatch(parent->astParent()->astOperand1(), "for")) {
const bool isconst = Token::simpleMatch(parent->astParent()->next(), "const");
const bool isvolatile = Token::simpleMatch(parent->astParent()->next(), "volatile");
Token * const autoToken = parent->astParent()->tokAt(isconst ? 2 : 1);
if (vt2->pointer) {
ValueType autovt(*vt2);
autovt.pointer--;
autovt.constness = 0;
autovt.volatileness = 0;
setValueType(autoToken, autovt);
setAutoTokenProperties(autoToken);
ValueType varvt(*vt2);
Expand All @@ -6746,6 +6774,12 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
else
varvt.constness |= 1;
}
if (isvolatile) {
if (varvt.pointer && varvt.reference != Reference::None)
varvt.volatileness |= (1 << varvt.pointer);
else
varvt.volatileness |= 1;
}
setValueType(parent->previous(), varvt);
auto *var = const_cast<Variable *>(parent->previous()->variable());
if (var) {
Expand Down Expand Up @@ -6800,6 +6834,12 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
else
autovt.constness |= 1;
}
if (autoToken->previous()->str() == "volatile") {
if (autovt.pointer && autovt.reference != Reference::None)
autovt.volatileness |= 2;
else
autovt.volatileness |= 1;
}
}
}

Expand All @@ -6812,6 +6852,8 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
autovt.pointer--;
if (isconst)
varvt.constness |= (1 << autovt.pointer);
if (isvolatile)
varvt.volatileness |= (1 << autovt.pointer);
setValueType(parent->previous(), varvt);
auto * var = const_cast<Variable *>(parent->previous()->variable());
if (var) {
Expand Down Expand Up @@ -7071,6 +7113,8 @@ static const Token* parsedecl(const Token* type,
parsedecl(type->type()->typeStart, valuetype, defaultSignedness, settings, isCpp);
else if (Token::Match(type, "const|constexpr"))
valuetype->constness |= (1 << (valuetype->pointer - pointer0));
else if (Token::simpleMatch(type, "volatile"))
valuetype->volatileness |= (1 << (valuetype->pointer - pointer0));
else if (settings.clang && type->str().size() > 2 && type->str().find("::") < type->str().find('<')) {
TokenList typeTokens(&settings);
std::string::size_type pos1 = 0;
Expand Down Expand Up @@ -7161,20 +7205,26 @@ static const Token* parsedecl(const Token* type,
if (vt->sign != ValueType::Sign::UNKNOWN_SIGN)
valuetype->sign = vt->sign;
valuetype->constness = vt->constness;
valuetype->volatileness = vt->volatileness;
valuetype->originalTypeName = vt->originalTypeName;
const bool hasConst = Token::simpleMatch(type->previous(), "const");
const bool hasVolatile = Token::simpleMatch(type->previous(), "volatile");
while (Token::Match(type, "%name%|*|&|&&|::") && !type->variable()) {
if (type->str() == "*") {
valuetype->pointer = 1;
if (hasConst)
valuetype->constness = 1;
if (hasVolatile)
valuetype->volatileness = 1;
} else if (type->str() == "&") {
valuetype->reference = Reference::LValue;
} else if (type->str() == "&&") {
valuetype->reference = Reference::RValue;
}
if (type->str() == "const")
valuetype->constness |= (1 << valuetype->pointer);
if (type->str() == "volatile")
valuetype->volatileness |= (1 << valuetype->pointer);
type = type->next();
}
break;
Expand Down Expand Up @@ -7336,7 +7386,8 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
} else if (tok->tokType() == Token::eChar || tok->tokType() == Token::eString) {
nonneg int const pointer = tok->tokType() == Token::eChar ? 0U : 1U;
nonneg int const constness = tok->tokType() == Token::eChar ? 0U : 1U;
ValueType valuetype(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::CHAR, pointer, constness);
nonneg int const volatileness = 0U;
ValueType valuetype(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::CHAR, pointer, constness, volatileness);

if (mIsCpp && mSettings.standards.cpp >= Standards::CPP20 && tok->isUtf8()) {
valuetype.originalTypeName = "char8_t";
Expand Down Expand Up @@ -7671,6 +7722,8 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
vt.typeScope = defScope;
if (fscope->function->isConst())
vt.constness = 1;
if (fscope->function->isVolatile())
vt.volatileness = 1;
setValueType(tok, vt);
}
}
Expand Down Expand Up @@ -7898,6 +7951,12 @@ std::string ValueType::dump() const
ret += '\"';
}

if (volatileness > 0) {
ret += " valueType-volatileness=\"";
ret += std::to_string(volatileness);
ret += '\"';
}

if (reference == Reference::None)
ret += " valueType-reference=\"None\"";
else if (reference == Reference::LValue)
Expand Down Expand Up @@ -7927,6 +7986,12 @@ bool ValueType::isConst(nonneg int indirect) const
return constness & (1 << (pointer - indirect));
}

bool ValueType::isVolatile(nonneg int indirect) const
{
if (indirect > pointer)
return false;
return volatileness & (1 << (pointer - indirect));
}
MathLib::bigint ValueType::typeSize(const Platform &platform, bool p) const
{
if (p && pointer)
Expand Down Expand Up @@ -7979,6 +8044,8 @@ std::string ValueType::str() const
std::string ret;
if (constness & 1)
ret = " const";
if (volatileness & 1)
ret = " volatile";
if (type == VOID)
ret += " void";
else if (isIntegral()) {
Expand Down Expand Up @@ -8028,6 +8095,8 @@ std::string ValueType::str() const
ret += " *";
if (constness & (2 << p))
ret += " const";
if (volatileness & (2 << p))
ret += " volatile";
}
if (reference == Reference::LValue)
ret += " &";
Expand Down Expand Up @@ -8064,8 +8133,12 @@ ValueType::MatchResult ValueType::matchParameter(const ValueType *call, const Va
if (call->pointer > 0) {
if ((call->constness | func->constness) != func->constness)
return ValueType::MatchResult::NOMATCH;
if ((call->volatileness | func->volatileness) != func->volatileness)
return ValueType::MatchResult::NOMATCH;
if (call->constness == 0 && func->constness != 0 && func->reference != Reference::None)
return ValueType::MatchResult::NOMATCH;
if (call->volatileness == 0 && func->volatileness != 0 && func->reference != Reference::None)
return ValueType::MatchResult::NOMATCH;
}
if (call->type != func->type || (call->isEnum() && !func->isEnum())) {
if (call->type == ValueType::Type::VOID || func->type == ValueType::Type::VOID)
Expand Down Expand Up @@ -8104,7 +8177,7 @@ ValueType::MatchResult ValueType::matchParameter(const ValueType *call, const Va
if (call->isIntegral() && func->isIntegral() && call->sign != ValueType::Sign::UNKNOWN_SIGN && func->sign != ValueType::Sign::UNKNOWN_SIGN && call->sign != func->sign)
return ValueType::MatchResult::FALLBACK1;

if (func->reference != Reference::None && func->constness > call->constness)
if (func->reference != Reference::None && (func->constness > call->constness || func->volatileness > call->volatileness))
return ValueType::MatchResult::FALLBACK1;

return ValueType::MatchResult::SAME;
Expand Down
10 changes: 10 additions & 0 deletions lib/symboldatabase.h
Original file line number Diff line number Diff line change
Expand Up @@ -1232,6 +1232,7 @@ class CPPCHECKLIB ValueType {
nonneg int bits{}; ///< bitfield bitcount
nonneg int pointer{}; ///< 0=>not pointer, 1=>*, 2=>**, 3=>***, etc
nonneg int constness{}; ///< bit 0=data, bit 1=*, bit 2=**
nonneg int volatileness{}; ///< bit 0=data, bit 1=*, bit 2=**
Reference reference = Reference::None; ///< Is the outermost indirection of this type a reference or rvalue
///< reference or not? pointer=2, Reference=LValue would be a T**&
const Scope* typeScope{}; ///< if the type definition is seen this point out the type scope
Expand All @@ -1258,6 +1259,13 @@ class CPPCHECKLIB ValueType {
pointer(p),
constness(c)
{}
ValueType(Sign s, Type t, nonneg int p, nonneg int c, nonneg int v)
: sign(s),
type(t),
pointer(p),
constness(c),
volatileness(v)
{}
ValueType(Sign s, Type t, nonneg int p, nonneg int c, std::string otn)
: sign(s),
type(t),
Expand Down Expand Up @@ -1294,6 +1302,8 @@ class CPPCHECKLIB ValueType {

bool isConst(nonneg int indirect = 0) const;

bool isVolatile(nonneg int indirect = 0) const;

MathLib::bigint typeSize(const Platform &platform, bool p=false) const;

/// Check if type is the same ignoring const and references
Expand Down
Loading

0 comments on commit 9a833de

Please sign in to comment.