diff --git a/lib/astutils.cpp b/lib/astutils.cpp index bc85cfab9..78252680e 100644 --- a/lib/astutils.cpp +++ b/lib/astutils.cpp @@ -738,7 +738,7 @@ std::vector getParentValueTypes(const Token* tok, const Settings* set const ValueType* vtCont = contTok->valueType(); if (!vtCont->containerTypeToken) return {}; - ValueType vtParent = ValueType::parseDecl(vtCont->containerTypeToken, *settings, true); // TODO: set isCpp + ValueType vtParent = ValueType::parseDecl(vtCont->containerTypeToken, *settings); return {std::move(vtParent)}; } if (Token::Match(tok->astParent(), "return|(|{|%assign%") && parent) { diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index 497babe1d..29a94f024 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -3228,7 +3228,7 @@ void CheckClass::checkThisUseAfterFree() for (const Variable &var : classScope->varlist) { // Find possible "self pointer".. pointer/smartpointer member variable of "self" type. if (var.valueType() && var.valueType()->smartPointerType != classScope->definedType && var.valueType()->typeScope != classScope) { - const ValueType valueType = ValueType::parseDecl(var.typeStartToken(), *mSettings, true); // this is only called for C++ + const ValueType valueType = ValueType::parseDecl(var.typeStartToken(), *mSettings); if (valueType.smartPointerType != classScope->definedType) continue; } diff --git a/lib/checktype.cpp b/lib/checktype.cpp index 3384bf69b..a15064122 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -437,7 +437,7 @@ void CheckType::checkFloatToIntegerOverflow() while (scope && scope->type != Scope::ScopeType::eLambda && scope->type != Scope::ScopeType::eFunction) scope = scope->nestedIn; if (scope && scope->type == Scope::ScopeType::eFunction && scope->function && scope->function->retDef) { - const ValueType &valueType = ValueType::parseDecl(scope->function->retDef, *mSettings, mTokenizer->isCPP()); + const ValueType &valueType = ValueType::parseDecl(scope->function->retDef, *mSettings); vtfloat = tok->astOperand1()->valueType(); checkFloatToIntegerOverflow(tok, &valueType, vtfloat, tok->astOperand1()->values()); } diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp index 7b91d6c4b..2e68aaa26 100644 --- a/lib/clangimport.cpp +++ b/lib/clangimport.cpp @@ -630,7 +630,7 @@ void clangimport::AstNode::setValueType(Token *tok) if (!decl.front()) break; - const ValueType valueType = ValueType::parseDecl(decl.front(), *mData->mSettings, true); // TODO: set isCpp + const ValueType valueType = ValueType::parseDecl(decl.front(), *mData->mSettings); if (valueType.type != ValueType::Type::UNKNOWN_TYPE) { tok->setValueType(new ValueType(valueType)); break; @@ -1545,7 +1545,7 @@ static void setValues(const Tokenizer *tokenizer, const SymbolDatabase *symbolDa for (Token *tok = const_cast(tokenizer->tokens()); tok; tok = tok->next()) { if (Token::simpleMatch(tok, "sizeof (")) { - ValueType vt = ValueType::parseDecl(tok->tokAt(2), *settings, tokenizer->isCPP()); + ValueType vt = ValueType::parseDecl(tok->tokAt(2), *settings); const int sz = vt.typeSize(settings->platform, true); if (sz <= 0) continue; diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index bfc04ae73..f64caa82e 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2214,12 +2214,13 @@ void Variable::evaluate(const Settings* settings) const Library * const lib = &settings->library; + // TODO: ValueType::parseDecl() is also performing a container lookup bool isContainer = false; if (mNameToken) setFlag(fIsArray, arrayDimensions(settings, isContainer)); if (mTypeStartToken) - setValueType(ValueType::parseDecl(mTypeStartToken,*settings, true)); // TODO: set isCpp + setValueType(ValueType::parseDecl(mTypeStartToken,*settings)); const Token* tok = mTypeStartToken; while (tok && tok->previous() && tok->previous()->isName()) @@ -2275,7 +2276,7 @@ void Variable::evaluate(const Settings* settings) setFlag(fIsClass, !lib->podtype(strtype) && !mTypeStartToken->isStandardType() && !isEnumType() && !isPointer() && !isReference() && strtype != "..."); setFlag(fIsStlType, Token::simpleMatch(mTypeStartToken, "std ::")); setFlag(fIsStlString, ::isStlStringType(mTypeStartToken)); - setFlag(fIsSmartPointer, lib->isSmartPointer(mTypeStartToken)); + setFlag(fIsSmartPointer, mTypeStartToken->isCpp() && lib->isSmartPointer(mTypeStartToken)); } if (mAccess == AccessControl::Argument) { tok = mNameToken; @@ -3558,7 +3559,7 @@ bool Type::isDerivedFrom(const std::string & ancestor) const bool Variable::arrayDimensions(const Settings* settings, bool& isContainer) { isContainer = false; - const Library::Container* container = settings->library.detectContainer(mTypeStartToken); + const Library::Container* container = (mTypeStartToken && mTypeStartToken->isCpp()) ? settings->library.detectContainer(mTypeStartToken) : nullptr; if (container && container->arrayLike_indexOp && container->size_templateArgNo > 0) { const Token* tok = Token::findsimplematch(mTypeStartToken, "<"); if (tok) { @@ -5653,7 +5654,7 @@ const Function* SymbolDatabase::findFunction(const Token* const tok) const return tok1->valueType()->typeScope->findFunction(tok, tok1->valueType()->constness == 1); if (tok1 && Token::Match(tok1->previous(), "%name% (") && tok1->previous()->function() && tok1->previous()->function()->retDef) { - ValueType vt = ValueType::parseDecl(tok1->previous()->function()->retDef, mSettings, mIsCpp); + ValueType vt = ValueType::parseDecl(tok1->previous()->function()->retDef, mSettings); if (vt.typeScope) return vt.typeScope->findFunction(tok, vt.constness == 1); } else if (Token::Match(tok1, "%var% .")) { @@ -5667,7 +5668,7 @@ const Function* SymbolDatabase::findFunction(const Token* const tok) const } else if (Token::simpleMatch(tok->previous()->astOperand1(), "(")) { const Token *castTok = tok->previous()->astOperand1(); if (castTok->isCast()) { - ValueType vt = ValueType::parseDecl(castTok->next(),mSettings, mIsCpp); + ValueType vt = ValueType::parseDecl(castTok->next(),mSettings); if (vt.typeScope) return vt.typeScope->findFunction(tok, vt.constness == 1); } @@ -5697,7 +5698,7 @@ const Function* SymbolDatabase::findFunction(const Token* const tok) const } // Check for constructor if (Token::Match(tok, "%name% (|{")) { - ValueType vt = ValueType::parseDecl(tok, mSettings, mIsCpp); + ValueType vt = ValueType::parseDecl(tok, mSettings); if (vt.typeScope) return vt.typeScope->findFunction(tok, false); } @@ -6991,7 +6992,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to } // Construct smart pointer - else if (mSettings.library.isSmartPointer(start)) { + else if (mIsCpp && mSettings.library.isSmartPointer(start)) { ValueType valuetype; if (parsedecl(start, &valuetype, mDefaultSignedness, mSettings, mIsCpp)) { setValueType(tok, valuetype); @@ -7066,7 +7067,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to } } } - if (tok->astParent() && Token::Match(tok->astOperand1(), "%name%|::")) { + if (mIsCpp && tok->astParent() && Token::Match(tok->astOperand1(), "%name%|::")) { const Token *typeStartToken = tok->astOperand1(); while (typeStartToken && typeStartToken->str() == "::") typeStartToken = typeStartToken->astOperand1(); @@ -7216,7 +7217,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to functionScope = functionScope->nestedIn; if (functionScope && functionScope->type == Scope::eFunction && functionScope->function && functionScope->function->retDef) { - ValueType vt = ValueType::parseDecl(functionScope->function->retDef, mSettings, mIsCpp); + ValueType vt = ValueType::parseDecl(functionScope->function->retDef, mSettings); setValueType(tok, vt); if (Token::simpleMatch(tok, "return {")) setValueType(tok->next(), vt); @@ -7314,10 +7315,10 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to createSymbolDatabaseSetVariablePointers(); } -ValueType ValueType::parseDecl(const Token *type, const Settings &settings, bool isCpp) +ValueType ValueType::parseDecl(const Token *type, const Settings &settings) { ValueType vt; - parsedecl(type, &vt, settings.platform.defaultSign == 'u' ? Sign::UNSIGNED : Sign::SIGNED, settings, isCpp); + parsedecl(type, &vt, settings.platform.defaultSign == 'u' ? Sign::UNSIGNED : Sign::SIGNED, settings, type->isCpp()); return vt; } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index d7c50ee7a..8b988e54a 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1268,7 +1268,7 @@ public: originalTypeName(std::move(otn)) {} - static ValueType parseDecl(const Token *type, const Settings &settings, bool isCpp); + static ValueType parseDecl(const Token *type, const Settings &settings); static Type typeFromString(const std::string &typestr, bool longType); diff --git a/lib/token.cpp b/lib/token.cpp index 5259a7d6b..6c832f3a7 100644 --- a/lib/token.cpp +++ b/lib/token.cpp @@ -2586,3 +2586,11 @@ Token* findLambdaEndScope(Token* tok) const Token* findLambdaEndScope(const Token* tok) { return findLambdaEndScope(const_cast(tok)); } + +bool Token::isCpp() const +{ + if (mTokensFrontBack && mTokensFrontBack->list) { + return mTokensFrontBack->list->isCPP(); + } + return true; // assume C++ by default +} diff --git a/lib/token.h b/lib/token.h index b17c294bd..b82326381 100644 --- a/lib/token.h +++ b/lib/token.h @@ -1484,6 +1484,9 @@ public: void setTokenDebug(TokenDebug td) { mImpl->mDebug = td; } + + /** defaults to C++ if it cannot be determined */ + bool isCpp() const; }; Token* findTypeEnd(Token* tok); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index c873f999e..ffd9c2095 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -760,7 +760,7 @@ static void setTokenValue(Token* tok, if (contains({ValueFlow::Value::ValueType::INT, ValueFlow::Value::ValueType::SYMBOLIC}, value.valueType) && Token::simpleMatch(parent->astOperand1(), "dynamic_cast")) return; - const ValueType &valueType = ValueType::parseDecl(castType, *settings, true); // TODO: set isCpp + const ValueType &valueType = ValueType::parseDecl(castType, *settings); if (value.isImpossible() && value.isIntValue() && value.intvalue < 0 && astIsUnsigned(tok) && valueType.sign == ValueType::SIGNED && tok->valueType() && ValueFlow::getSizeOf(*tok->valueType(), settings) >= ValueFlow::getSizeOf(valueType, settings)) @@ -1095,7 +1095,7 @@ static void setTokenValueCast(Token *parent, const ValueType &valueType, const V static nonneg int getSizeOfType(const Token *typeTok, const Settings *settings) { - const ValueType &valueType = ValueType::parseDecl(typeTok, *settings, true); // TODO: set isCpp + const ValueType &valueType = ValueType::parseDecl(typeTok, *settings); return ValueFlow::getSizeOf(valueType, settings); } @@ -1298,7 +1298,7 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, b setTokenValue(tok->next(), std::move(value), settings); } } else if (!tok2->type()) { - const ValueType& vt = ValueType::parseDecl(tok2, *settings, true); // TODO: set isCpp + const ValueType& vt = ValueType::parseDecl(tok2, *settings); size_t sz = ValueFlow::getSizeOf(vt, settings); const Token* brac = tok2->astParent(); while (Token::simpleMatch(brac, "[")) { @@ -4765,7 +4765,7 @@ static bool isContainerOfPointers(const Token* tok, const Settings* settings) return true; } - ValueType vt = ValueType::parseDecl(tok, *settings, true); // TODO: set isCpp + ValueType vt = ValueType::parseDecl(tok, *settings); return vt.pointer > 0; } @@ -8628,7 +8628,7 @@ static bool valueFlowIsSameContainerType(const ValueType& contType, const Token* if (!tok || !tok->valueType() || !tok->valueType()->containerTypeToken) return false; - const ValueType tokType = ValueType::parseDecl(tok->valueType()->containerTypeToken, *settings, true); + const ValueType tokType = ValueType::parseDecl(tok->valueType()->containerTypeToken, *settings); return contType.isTypeEqual(&tokType); } @@ -8648,7 +8648,7 @@ static std::vector getInitListSize(const Token* tok, if (valueType->container->stdStringLike) { initList = astIsGenericChar(args[0]) && !astIsPointer(args[0]); } else if (containerTypeToken && settings) { - ValueType vt = ValueType::parseDecl(containerTypeToken, *settings, true); // TODO: set isCpp + ValueType vt = ValueType::parseDecl(containerTypeToken, *settings); if (vt.pointer > 0 && astIsPointer(args[0])) initList = true; else if (vt.type == ValueType::ITERATOR && astIsIterator(args[0])) @@ -9108,7 +9108,7 @@ static bool getMinMaxValues(const std::string &typestr, const Settings *settings return false; typeTokens.simplifyPlatformTypes(); typeTokens.simplifyStdType(); - const ValueType &vt = ValueType::parseDecl(typeTokens.front(), *settings, true); // TODO: set isCpp + const ValueType &vt = ValueType::parseDecl(typeTokens.front(), *settings); return getMinMaxValues(&vt, settings->platform, minvalue, maxvalue); }