Skip to content

Commit 7c790ca

Browse files
authored
#12400: dump file: Add volatileness to ValueType (#5967)
1 parent 889f15e commit 7c790ca

3 files changed

Lines changed: 129 additions & 4 deletions

File tree

lib/symboldatabase.cpp

Lines changed: 77 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2437,6 +2437,7 @@ void Variable::setValueType(const ValueType &valueType)
24372437
if ((mValueType->pointer > 0) && (!isArray() || Token::Match(mNameToken->previous(), "( * %name% )")))
24382438
setFlag(fIsPointer, true);
24392439
setFlag(fIsConst, mValueType->constness & (1U << mValueType->pointer));
2440+
setFlag(fIsVolatile, mValueType->volatileness & (1U << mValueType->pointer));
24402441
if (mValueType->smartPointerType)
24412442
setFlag(fIsSmartPointer, true);
24422443
}
@@ -4354,6 +4355,10 @@ void SymbolDatabase::printXml(std::ostream &out) const
43544355
outs += " constness=\"";
43554356
outs += std::to_string(var->valueType()->constness);
43564357
outs += '\"';
4358+
4359+
outs += " volatileness=\"";
4360+
outs += std::to_string(var->valueType()->volatileness);
4361+
outs += '\"';
43574362
}
43584363
outs += " isArray=\"";
43594364
outs += bool_to_string(var->isArray());
@@ -5608,7 +5613,8 @@ static bool hasMatchingConstructor(const Scope* classScope, const ValueType* arg
56085613
vt->type == argType->type &&
56095614
(argType->sign == ValueType::Sign::UNKNOWN_SIGN || vt->sign == argType->sign) &&
56105615
vt->pointer == argType->pointer &&
5611-
(vt->constness & 1) >= (argType->constness & 1);
5616+
(vt->constness & 1) >= (argType->constness & 1) &&
5617+
(vt->volatileness & 1) >= (argType->volatileness & 1);
56125618
});
56135619
}
56145620

@@ -5717,6 +5723,8 @@ const Function* Scope::findFunction(const Token *tok, bool requireConst) const
57175723
{
57185724
if (typeToken->str() == "const")
57195725
ret.constness |= (1 << ret.pointer);
5726+
else if (typeToken->str() == "volatile")
5727+
ret.volatileness |= (1 << ret.pointer);
57205728
else if (typeToken->str() == "*")
57215729
ret.pointer++;
57225730
else if (typeToken->str() == "<") {
@@ -6454,6 +6462,8 @@ void SymbolDatabase::setValueType(Token* tok, const Variable& var, SourceLocatio
64546462
const ValueType * const vt = tok->astOperand1()->valueType();
64556463
if (vt && (vt->constness & 1) != 0)
64566464
valuetype.constness |= 1;
6465+
if (vt && (vt->volatileness & 1) != 0)
6466+
valuetype.volatileness |= 1;
64576467
}
64586468
setValueType(tok, valuetype);
64596469
}
@@ -6549,6 +6559,8 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
65496559
if (parsedecl(vt1->containerTypeToken, &item, mDefaultSignedness, mSettings, mIsCpp)) {
65506560
if (item.constness == 0)
65516561
item.constness = vt1->constness;
6562+
if (item.volatileness == 0)
6563+
item.volatileness = vt1->volatileness;
65526564
if (isContainerYieldPointer(vt1->container->getYield(parent->next()->str())))
65536565
item.pointer += 1;
65546566
else
@@ -6583,10 +6595,14 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
65836595
ValueType vt(*vt2);
65846596
if (vt.constness & (1 << vt.pointer))
65856597
vt.constness &= ~(1 << vt.pointer);
6598+
if (vt.volatileness & (1 << vt.pointer))
6599+
vt.volatileness &= ~(1 << vt.pointer);
65866600
if (autoTok->strAt(1) == "*" && vt.pointer)
65876601
vt.pointer--;
65886602
if (Token::Match(autoTok->tokAt(-1), "const|constexpr"))
65896603
vt.constness |= (1 << vt.pointer);
6604+
if (Token::simpleMatch(autoTok->tokAt(-1), "volatile"))
6605+
vt.volatileness |= (1 << vt.pointer);
65906606
setValueType(autoTok, vt);
65916607
setAutoTokenProperties(autoTok);
65926608
if (vt2->pointer > vt.pointer)
@@ -6601,10 +6617,16 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
66016617
vt2_.pointer = 1;
66026618
if ((vt.constness & (1 << vt2->pointer)) != 0)
66036619
vt2_.constness |= (1 << vt2->pointer);
6604-
if (!Token::Match(autoTok->tokAt(1), "*|&"))
6620+
if ((vt.volatileness & (1 << vt2->pointer)) != 0)
6621+
vt2_.volatileness |= (1 << vt2->pointer);
6622+
if (!Token::Match(autoTok->tokAt(1), "*|&")) {
66056623
vt2_.constness = vt.constness;
6624+
vt2_.volatileness = vt.volatileness;
6625+
}
66066626
if (Token::simpleMatch(autoTok->tokAt(1), "* const"))
66076627
vt2_.constness |= (1 << vt2->pointer);
6628+
if (Token::simpleMatch(autoTok->tokAt(1), "* volatile"))
6629+
vt2_.volatileness |= (1 << vt2->pointer);
66086630
var->setValueType(vt2_);
66096631
if (vt2->typeScope && vt2->typeScope->definedType) {
66106632
var->type(vt2->typeScope->definedType);
@@ -6655,6 +6677,8 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
66556677
if (parsedecl(valuetype.containerTypeToken, &vt, mDefaultSignedness, mSettings, mIsCpp)) {
66566678
if (vt.constness == 0)
66576679
vt.constness = valuetype.constness;
6680+
if (vt.volatileness == 0)
6681+
vt.volatileness = valuetype.volatileness;
66586682
vt.reference = Reference::LValue;
66596683
setValueType(parent, vt);
66606684
return;
@@ -6667,6 +6691,8 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
66676691
if (parsedecl(valuetype.smartPointerTypeToken, &vt, mDefaultSignedness, mSettings, mIsCpp)) {
66686692
if (vt.constness == 0)
66696693
vt.constness = valuetype.constness;
6694+
if (vt.volatileness == 0)
6695+
vt.volatileness = valuetype.volatileness;
66706696
setValueType(parent, vt);
66716697
return;
66726698
}
@@ -6729,11 +6755,13 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
67296755
!parent->previous()->valueType() &&
67306756
Token::simpleMatch(parent->astParent()->astOperand1(), "for")) {
67316757
const bool isconst = Token::simpleMatch(parent->astParent()->next(), "const");
6758+
const bool isvolatile = Token::simpleMatch(parent->astParent()->next(), "volatile");
67326759
Token * const autoToken = parent->astParent()->tokAt(isconst ? 2 : 1);
67336760
if (vt2->pointer) {
67346761
ValueType autovt(*vt2);
67356762
autovt.pointer--;
67366763
autovt.constness = 0;
6764+
autovt.volatileness = 0;
67376765
setValueType(autoToken, autovt);
67386766
setAutoTokenProperties(autoToken);
67396767
ValueType varvt(*vt2);
@@ -6746,6 +6774,12 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
67466774
else
67476775
varvt.constness |= 1;
67486776
}
6777+
if (isvolatile) {
6778+
if (varvt.pointer && varvt.reference != Reference::None)
6779+
varvt.volatileness |= (1 << varvt.pointer);
6780+
else
6781+
varvt.volatileness |= 1;
6782+
}
67496783
setValueType(parent->previous(), varvt);
67506784
auto *var = const_cast<Variable *>(parent->previous()->variable());
67516785
if (var) {
@@ -6800,6 +6834,12 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
68006834
else
68016835
autovt.constness |= 1;
68026836
}
6837+
if (autoToken->previous()->str() == "volatile") {
6838+
if (autovt.pointer && autovt.reference != Reference::None)
6839+
autovt.volatileness |= 2;
6840+
else
6841+
autovt.volatileness |= 1;
6842+
}
68036843
}
68046844
}
68056845

@@ -6812,6 +6852,8 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source
68126852
autovt.pointer--;
68136853
if (isconst)
68146854
varvt.constness |= (1 << autovt.pointer);
6855+
if (isvolatile)
6856+
varvt.volatileness |= (1 << autovt.pointer);
68156857
setValueType(parent->previous(), varvt);
68166858
auto * var = const_cast<Variable *>(parent->previous()->variable());
68176859
if (var) {
@@ -7071,6 +7113,8 @@ static const Token* parsedecl(const Token* type,
70717113
parsedecl(type->type()->typeStart, valuetype, defaultSignedness, settings, isCpp);
70727114
else if (Token::Match(type, "const|constexpr"))
70737115
valuetype->constness |= (1 << (valuetype->pointer - pointer0));
7116+
else if (Token::simpleMatch(type, "volatile"))
7117+
valuetype->volatileness |= (1 << (valuetype->pointer - pointer0));
70747118
else if (settings.clang && type->str().size() > 2 && type->str().find("::") < type->str().find('<')) {
70757119
TokenList typeTokens(&settings);
70767120
std::string::size_type pos1 = 0;
@@ -7161,20 +7205,26 @@ static const Token* parsedecl(const Token* type,
71617205
if (vt->sign != ValueType::Sign::UNKNOWN_SIGN)
71627206
valuetype->sign = vt->sign;
71637207
valuetype->constness = vt->constness;
7208+
valuetype->volatileness = vt->volatileness;
71647209
valuetype->originalTypeName = vt->originalTypeName;
71657210
const bool hasConst = Token::simpleMatch(type->previous(), "const");
7211+
const bool hasVolatile = Token::simpleMatch(type->previous(), "volatile");
71667212
while (Token::Match(type, "%name%|*|&|&&|::") && !type->variable()) {
71677213
if (type->str() == "*") {
71687214
valuetype->pointer = 1;
71697215
if (hasConst)
71707216
valuetype->constness = 1;
7217+
if (hasVolatile)
7218+
valuetype->volatileness = 1;
71717219
} else if (type->str() == "&") {
71727220
valuetype->reference = Reference::LValue;
71737221
} else if (type->str() == "&&") {
71747222
valuetype->reference = Reference::RValue;
71757223
}
71767224
if (type->str() == "const")
71777225
valuetype->constness |= (1 << valuetype->pointer);
7226+
if (type->str() == "volatile")
7227+
valuetype->volatileness |= (1 << valuetype->pointer);
71787228
type = type->next();
71797229
}
71807230
break;
@@ -7336,7 +7386,8 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
73367386
} else if (tok->tokType() == Token::eChar || tok->tokType() == Token::eString) {
73377387
nonneg int const pointer = tok->tokType() == Token::eChar ? 0U : 1U;
73387388
nonneg int const constness = tok->tokType() == Token::eChar ? 0U : 1U;
7339-
ValueType valuetype(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::CHAR, pointer, constness);
7389+
nonneg int const volatileness = 0U;
7390+
ValueType valuetype(ValueType::Sign::UNKNOWN_SIGN, ValueType::Type::CHAR, pointer, constness, volatileness);
73407391

73417392
if (mIsCpp && mSettings.standards.cpp >= Standards::CPP20 && tok->isUtf8()) {
73427393
valuetype.originalTypeName = "char8_t";
@@ -7671,6 +7722,8 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
76717722
vt.typeScope = defScope;
76727723
if (fscope->function->isConst())
76737724
vt.constness = 1;
7725+
if (fscope->function->isVolatile())
7726+
vt.volatileness = 1;
76747727
setValueType(tok, vt);
76757728
}
76767729
}
@@ -7898,6 +7951,12 @@ std::string ValueType::dump() const
78987951
ret += '\"';
78997952
}
79007953

7954+
if (volatileness > 0) {
7955+
ret += " valueType-volatileness=\"";
7956+
ret += std::to_string(volatileness);
7957+
ret += '\"';
7958+
}
7959+
79017960
if (reference == Reference::None)
79027961
ret += " valueType-reference=\"None\"";
79037962
else if (reference == Reference::LValue)
@@ -7927,6 +7986,12 @@ bool ValueType::isConst(nonneg int indirect) const
79277986
return constness & (1 << (pointer - indirect));
79287987
}
79297988

7989+
bool ValueType::isVolatile(nonneg int indirect) const
7990+
{
7991+
if (indirect > pointer)
7992+
return false;
7993+
return volatileness & (1 << (pointer - indirect));
7994+
}
79307995
MathLib::bigint ValueType::typeSize(const Platform &platform, bool p) const
79317996
{
79327997
if (p && pointer)
@@ -7979,6 +8044,8 @@ std::string ValueType::str() const
79798044
std::string ret;
79808045
if (constness & 1)
79818046
ret = " const";
8047+
if (volatileness & 1)
8048+
ret = " volatile";
79828049
if (type == VOID)
79838050
ret += " void";
79848051
else if (isIntegral()) {
@@ -8028,6 +8095,8 @@ std::string ValueType::str() const
80288095
ret += " *";
80298096
if (constness & (2 << p))
80308097
ret += " const";
8098+
if (volatileness & (2 << p))
8099+
ret += " volatile";
80318100
}
80328101
if (reference == Reference::LValue)
80338102
ret += " &";
@@ -8064,8 +8133,12 @@ ValueType::MatchResult ValueType::matchParameter(const ValueType *call, const Va
80648133
if (call->pointer > 0) {
80658134
if ((call->constness | func->constness) != func->constness)
80668135
return ValueType::MatchResult::NOMATCH;
8136+
if ((call->volatileness | func->volatileness) != func->volatileness)
8137+
return ValueType::MatchResult::NOMATCH;
80678138
if (call->constness == 0 && func->constness != 0 && func->reference != Reference::None)
80688139
return ValueType::MatchResult::NOMATCH;
8140+
if (call->volatileness == 0 && func->volatileness != 0 && func->reference != Reference::None)
8141+
return ValueType::MatchResult::NOMATCH;
80698142
}
80708143
if (call->type != func->type || (call->isEnum() && !func->isEnum())) {
80718144
if (call->type == ValueType::Type::VOID || func->type == ValueType::Type::VOID)
@@ -8104,7 +8177,7 @@ ValueType::MatchResult ValueType::matchParameter(const ValueType *call, const Va
81048177
if (call->isIntegral() && func->isIntegral() && call->sign != ValueType::Sign::UNKNOWN_SIGN && func->sign != ValueType::Sign::UNKNOWN_SIGN && call->sign != func->sign)
81058178
return ValueType::MatchResult::FALLBACK1;
81068179

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

81108183
return ValueType::MatchResult::SAME;

lib/symboldatabase.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1232,6 +1232,7 @@ class CPPCHECKLIB ValueType {
12321232
nonneg int bits{}; ///< bitfield bitcount
12331233
nonneg int pointer{}; ///< 0=>not pointer, 1=>*, 2=>**, 3=>***, etc
12341234
nonneg int constness{}; ///< bit 0=data, bit 1=*, bit 2=**
1235+
nonneg int volatileness{}; ///< bit 0=data, bit 1=*, bit 2=**
12351236
Reference reference = Reference::None; ///< Is the outermost indirection of this type a reference or rvalue
12361237
///< reference or not? pointer=2, Reference=LValue would be a T**&
12371238
const Scope* typeScope{}; ///< if the type definition is seen this point out the type scope
@@ -1258,6 +1259,13 @@ class CPPCHECKLIB ValueType {
12581259
pointer(p),
12591260
constness(c)
12601261
{}
1262+
ValueType(Sign s, Type t, nonneg int p, nonneg int c, nonneg int v)
1263+
: sign(s),
1264+
type(t),
1265+
pointer(p),
1266+
constness(c),
1267+
volatileness(v)
1268+
{}
12611269
ValueType(Sign s, Type t, nonneg int p, nonneg int c, std::string otn)
12621270
: sign(s),
12631271
type(t),
@@ -1294,6 +1302,8 @@ class CPPCHECKLIB ValueType {
12941302

12951303
bool isConst(nonneg int indirect = 0) const;
12961304

1305+
bool isVolatile(nonneg int indirect = 0) const;
1306+
12971307
MathLib::bigint typeSize(const Platform &platform, bool p=false) const;
12981308

12991309
/// Check if type is the same ignoring const and references

0 commit comments

Comments
 (0)