@@ -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+ }
79307995MathLib::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;
0 commit comments