From 0e1cd8b2acdde89829094bfe71fb6c7b4b9cb30b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oliver=20St=C3=B6neberg?= Date: Sun, 21 Aug 2022 17:11:22 +0200 Subject: [PATCH] do not do C++ processing for C code in `parsedecl()` (#4304) --- lib/checkclass.cpp | 2 +- lib/checktype.cpp | 2 +- lib/clangimport.cpp | 4 +-- lib/symboldatabase.cpp | 58 ++++++++++++++++++++++-------------------- lib/symboldatabase.h | 2 +- lib/valueflow.cpp | 14 +++++----- 6 files changed, 42 insertions(+), 40 deletions(-) diff --git a/lib/checkclass.cpp b/lib/checkclass.cpp index a62cd183a..1174bfa19 100644 --- a/lib/checkclass.cpp +++ b/lib/checkclass.cpp @@ -2914,7 +2914,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); + const ValueType valueType = ValueType::parseDecl(var.typeStartToken(), mSettings, true); // this is only called for C++ if (valueType.smartPointerType != classScope->definedType) continue; } diff --git a/lib/checktype.cpp b/lib/checktype.cpp index 58e3b51c6..0254a7cc2 100644 --- a/lib/checktype.cpp +++ b/lib/checktype.cpp @@ -410,7 +410,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); + const ValueType &valueType = ValueType::parseDecl(scope->function->retDef, mSettings, mTokenizer->isCPP()); vtfloat = tok->astOperand1()->valueType(); floatValues = &tok->astOperand1()->values(); checkFloatToIntegerOverflow(tok, &valueType, vtfloat, floatValues); diff --git a/lib/clangimport.cpp b/lib/clangimport.cpp index 5d7b54cce..e5977b4c4 100644 --- a/lib/clangimport.cpp +++ b/lib/clangimport.cpp @@ -628,7 +628,7 @@ void clangimport::AstNode::setValueType(Token *tok) if (!decl.front()) break; - ValueType valueType = ValueType::parseDecl(decl.front(), mData->mSettings); + ValueType valueType = ValueType::parseDecl(decl.front(), mData->mSettings, true); // TODO: set isCpp if (valueType.type != ValueType::Type::UNKNOWN_TYPE) { tok->setValueType(new ValueType(valueType)); break; @@ -1542,7 +1542,7 @@ static void setValues(Tokenizer *tokenizer, SymbolDatabase *symbolDatabase) for (Token *tok = const_cast(tokenizer->tokens()); tok; tok = tok->next()) { if (Token::simpleMatch(tok, "sizeof (")) { - ValueType vt = ValueType::parseDecl(tok->tokAt(2), settings); + ValueType vt = ValueType::parseDecl(tok->tokAt(2), settings, tokenizer->isCPP()); int sz = vt.typeSize(*settings, true); if (sz <= 0) continue; diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 73bc722df..e1a34fbd6 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -2132,7 +2132,7 @@ void Variable::evaluate(const Settings* settings) setFlag(fIsArray, arrayDimensions(settings, &isContainer)); if (mTypeStartToken) - setValueType(ValueType::parseDecl(mTypeStartToken,settings)); + setValueType(ValueType::parseDecl(mTypeStartToken,settings, true)); // TODO: set isCpp const Token* tok = mTypeStartToken; while (tok && tok->previous() && tok->previous()->isName()) @@ -5502,7 +5502,7 @@ const Function* SymbolDatabase::findFunction(const Token *tok) const return tok1->valueType()->typeScope->findFunction(tok, tok1->valueType()->constness == 1); } else if (tok1 && Token::Match(tok1->previous(), "%name% (") && tok1->previous()->function() && tok1->previous()->function()->retDef) { - ValueType vt = ValueType::parseDecl(tok1->previous()->function()->retDef, mSettings); + ValueType vt = ValueType::parseDecl(tok1->previous()->function()->retDef, mSettings, mIsCpp); if (vt.typeScope) return vt.typeScope->findFunction(tok, vt.constness == 1); } else if (Token::Match(tok1, "%var% .")) { @@ -5514,7 +5514,7 @@ const Function* SymbolDatabase::findFunction(const Token *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); + ValueType vt = ValueType::parseDecl(castTok->next(),mSettings, mIsCpp); if (vt.typeScope) return vt.typeScope->findFunction(tok, vt.constness == 1); } @@ -5532,7 +5532,7 @@ const Function* SymbolDatabase::findFunction(const Token *tok) const } // Check for constructor if (Token::Match(tok, "%name% (|{")) { - ValueType vt = ValueType::parseDecl(tok, mSettings); + ValueType vt = ValueType::parseDecl(tok, mSettings, mIsCpp); if (vt.typeScope) return vt.typeScope->findFunction(tok, false); } @@ -5939,6 +5939,7 @@ static const Token* parsedecl(const Token* type, ValueType* const valuetype, ValueType::Sign defaultSignedness, const Settings* settings, + bool isCpp, SourceLocation loc = SourceLocation::current()); void SymbolDatabase::setValueType(Token* tok, const Variable& var, SourceLocation loc) @@ -5955,7 +5956,7 @@ void SymbolDatabase::setValueType(Token* tok, const Variable& var, SourceLocatio valuetype.containerTypeToken = var.valueType()->containerTypeToken; } valuetype.smartPointerType = var.smartPointerType(); - if (parsedecl(var.typeStartToken(), &valuetype, mDefaultSignedness, mSettings)) { + if (parsedecl(var.typeStartToken(), &valuetype, mDefaultSignedness, mSettings, mIsCpp)) { if (tok->str() == "." && tok->astOperand1()) { const ValueType * const vt = tok->astOperand1()->valueType(); if (vt && (vt->constness & 1) != 0) @@ -6050,7 +6051,7 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source if (vt1 && vt1->container && vt1->containerTypeToken && Token::Match(parent, ". %name% (") && isContainerYieldElement(vt1->container->getYield(parent->next()->str()))) { ValueType item; - if (parsedecl(vt1->containerTypeToken, &item, mDefaultSignedness, mSettings)) { + if (parsedecl(vt1->containerTypeToken, &item, mDefaultSignedness, mSettings, mIsCpp)) { if (item.constness == 0) item.constness = vt1->constness; if (isContainerYieldPointer(vt1->container->getYield(parent->next()->str()))) @@ -6152,7 +6153,7 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source if (parent->str() == "*" && !parent->astOperand2() && valuetype.type == ValueType::Type::ITERATOR && valuetype.containerTypeToken) { ValueType vt; - if (parsedecl(valuetype.containerTypeToken, &vt, mDefaultSignedness, mSettings)) { + if (parsedecl(valuetype.containerTypeToken, &vt, mDefaultSignedness, mSettings, mIsCpp)) { if (vt.constness == 0) vt.constness = valuetype.constness; vt.reference = Reference::LValue; @@ -6164,7 +6165,7 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source if (parent->str() == "*" && !parent->astOperand2() && valuetype.type == ValueType::Type::SMART_POINTER && valuetype.smartPointerTypeToken) { ValueType vt; - if (parsedecl(valuetype.smartPointerTypeToken, &vt, mDefaultSignedness, mSettings)) { + if (parsedecl(valuetype.smartPointerTypeToken, &vt, mDefaultSignedness, mSettings, mIsCpp)) { if (vt.constness == 0) vt.constness = valuetype.constness; setValueType(parent, vt); @@ -6273,7 +6274,7 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source autovt.smartPointerType = templateArgType; autovt.type = ValueType::Type::NONSTD; } - } else if (parsedecl(vt2->containerTypeToken, &autovt, mDefaultSignedness, mSettings)) { + } else if (parsedecl(vt2->containerTypeToken, &autovt, mDefaultSignedness, mSettings, mIsCpp)) { setType = true; templateArgType = vt2->containerTypeToken->type(); } @@ -6301,7 +6302,7 @@ void SymbolDatabase::setValueType(Token* tok, const ValueType& valuetype, Source if (vt1 && vt1->containerTypeToken && parent->str() == "[") { ValueType vtParent; - if (parsedecl(vt1->containerTypeToken, &vtParent, mDefaultSignedness, mSettings)) { + if (parsedecl(vt1->containerTypeToken, &vtParent, mDefaultSignedness, mSettings, mIsCpp)) { setValueType(parent, vtParent); return; } @@ -6431,6 +6432,7 @@ static const Token* parsedecl(const Token* type, ValueType* const valuetype, ValueType::Sign defaultSignedness, const Settings* settings, + bool isCpp, SourceLocation loc) { if (settings->debugnormal || settings->debugwarnings) @@ -6491,7 +6493,7 @@ static const Token* parsedecl(const Token* type, if (valuetype->type == ValueType::Type::UNKNOWN_TYPE && type->type() && type->type()->isTypeAlias() && type->type()->typeStart && type->type()->typeStart->str() != type->str() && type->type()->typeStart != previousType) - parsedecl(type->type()->typeStart, valuetype, defaultSignedness, settings); + parsedecl(type->type()->typeStart, valuetype, defaultSignedness, settings, isCpp); else if (Token::Match(type, "const|constexpr")) valuetype->constness |= (1 << (valuetype->pointer - pointer0)); else if (settings->clang && type->str().size() > 2 && type->str().find("::") < type->str().find("<")) { @@ -6521,7 +6523,7 @@ static const Token* parsedecl(const Token* type, if (valuetype->typeScope) valuetype->type = (scope->type == Scope::ScopeType::eClass) ? ValueType::Type::RECORD : ValueType::Type::NONSTD; } - } else if (const Library::Container* container = settings->library.detectContainerOrIterator(type, &isIterator)) { + } else if (const Library::Container* container = (isCpp ? settings->library.detectContainerOrIterator(type, &isIterator) : nullptr)) { if (isIterator) valuetype->type = ValueType::Type::ITERATOR; else @@ -6543,7 +6545,7 @@ static const Token* parsedecl(const Token* type, // we are past the end of the type type = type->previous(); continue; - } else if (const Library::SmartPointer* smartPointer = settings->library.detectSmartPointer(type)) { + } else if (const Library::SmartPointer* smartPointer = (isCpp ? settings->library.detectSmartPointer(type) : nullptr)) { const Token* argTok = Token::findsimplematch(type, "<"); if (!argTok) break; @@ -6720,7 +6722,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to const Function *function = getOperatorFunction(tok); if (function) { ValueType vt; - parsedecl(function->retDef, &vt, mDefaultSignedness, mSettings); + parsedecl(function->retDef, &vt, mDefaultSignedness, mSettings, mIsCpp); setValueType(tok, vt); continue; } @@ -6755,21 +6757,21 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to // cast if (tok->isCast() && !tok->astOperand2() && Token::Match(tok, "( %name%")) { ValueType valuetype; - if (Token::simpleMatch(parsedecl(tok->next(), &valuetype, mDefaultSignedness, mSettings), ")")) + if (Token::simpleMatch(parsedecl(tok->next(), &valuetype, mDefaultSignedness, mSettings, mIsCpp), ")")) setValueType(tok, valuetype); } // C++ cast else if (tok->astOperand2() && Token::Match(tok->astOperand1(), "static_cast|const_cast|dynamic_cast|reinterpret_cast < %name%") && tok->astOperand1()->linkAt(1)) { ValueType valuetype; - if (Token::simpleMatch(parsedecl(tok->astOperand1()->tokAt(2), &valuetype, mDefaultSignedness, mSettings), ">")) + if (Token::simpleMatch(parsedecl(tok->astOperand1()->tokAt(2), &valuetype, mDefaultSignedness, mSettings, mIsCpp), ">")) setValueType(tok, valuetype); } // Construct smart pointer else if (mSettings->library.isSmartPointer(start)) { ValueType valuetype; - if (parsedecl(start, &valuetype, mDefaultSignedness, mSettings)) { + if (parsedecl(start, &valuetype, mDefaultSignedness, mSettings, mIsCpp)) { setValueType(tok, valuetype); setValueType(tok->astOperand1(), valuetype); } @@ -6779,7 +6781,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to // function else if (tok->previous() && tok->previous()->function() && tok->previous()->function()->retDef) { ValueType valuetype; - if (parsedecl(tok->previous()->function()->retDef, &valuetype, mDefaultSignedness, mSettings)) + if (parsedecl(tok->previous()->function()->retDef, &valuetype, mDefaultSignedness, mSettings, mIsCpp)) setValueType(tok, valuetype); } @@ -6793,7 +6795,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to if (Token::Match(tok, "( %type% %type%| *| *| )")) { ValueType vt; - if (parsedecl(tok->next(), &vt, mDefaultSignedness, mSettings)) { + if (parsedecl(tok->next(), &vt, mDefaultSignedness, mSettings, mIsCpp)) { setValueType(tok->next(), vt); } } @@ -6835,7 +6837,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to // Aggregate constructor if (Token::Match(tok->previous(), "%name%")) { ValueType valuetype; - if (parsedecl(tok->previous(), &valuetype, mDefaultSignedness, mSettings)) { + if (parsedecl(tok->previous(), &valuetype, mDefaultSignedness, mSettings, mIsCpp)) { if (valuetype.typeScope) { setValueType(tok, valuetype); continue; @@ -6849,7 +6851,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to if (mSettings->library.detectContainerOrIterator(typeStartToken) || mSettings->library.detectSmartPointer(typeStartToken)) { ValueType vt; - if (parsedecl(typeStartToken, &vt, mDefaultSignedness, mSettings)) { + if (parsedecl(typeStartToken, &vt, mDefaultSignedness, mSettings, mIsCpp)) { setValueType(tok, vt); continue; } @@ -6859,7 +6861,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to if ((e == "std::make_shared" || e == "std::make_unique") && Token::Match(tok->astOperand1(), ":: %name% < %name%")) { ValueType vt; - parsedecl(tok->astOperand1()->tokAt(3), &vt, mDefaultSignedness, mSettings); + parsedecl(tok->astOperand1()->tokAt(3), &vt, mDefaultSignedness, mSettings, mIsCpp); if (vt.typeScope) { vt.smartPointerType = vt.typeScope->definedType; vt.typeScope = nullptr; @@ -6888,7 +6890,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to std::istringstream istr(typestr+";"); tokenList.createTokens(istr); tokenList.simplifyStdType(); - if (parsedecl(tokenList.front(), &valuetype, mDefaultSignedness, mSettings)) { + if (parsedecl(tokenList.front(), &valuetype, mDefaultSignedness, mSettings, mIsCpp)) { valuetype.originalTypeName = typestr; setValueType(tok, valuetype); } @@ -6923,7 +6925,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to ValueType vt; tokenList.simplifyPlatformTypes(); tokenList.simplifyStdType(); - if (parsedecl(tokenList.front(), &vt, mDefaultSignedness, mSettings)) { + if (parsedecl(tokenList.front(), &vt, mDefaultSignedness, mSettings, mIsCpp)) { vt.originalTypeName = typestr; setValueType(tok, vt); } @@ -6935,7 +6937,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); + ValueType vt = ValueType::parseDecl(functionScope->function->retDef, mSettings, mIsCpp); setValueType(tok, vt); if (Token::simpleMatch(tok, "return {")) setValueType(tok->next(), vt); @@ -6996,7 +6998,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to fscope = fscope->nestedIn; if (fscope && fscope->function && fscope->function->retDef) { ValueType vt; - parsedecl(fscope->function->retDef, &vt, mDefaultSignedness, mSettings); + parsedecl(fscope->function->retDef, &vt, mDefaultSignedness, mSettings, mIsCpp); setValueType(tok, vt); } } @@ -7016,10 +7018,10 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to createSymbolDatabaseSetVariablePointers(); } -ValueType ValueType::parseDecl(const Token *type, const Settings *settings) +ValueType ValueType::parseDecl(const Token *type, const Settings *settings, bool isCpp) { ValueType vt; - parsedecl(type, &vt, settings->defaultSign == 'u' ? Sign::UNSIGNED : Sign::SIGNED, settings); + parsedecl(type, &vt, settings->defaultSign == 'u' ? Sign::UNSIGNED : Sign::SIGNED, settings, isCpp); return vt; } diff --git a/lib/symboldatabase.h b/lib/symboldatabase.h index 5b5fb6711..46851df4b 100644 --- a/lib/symboldatabase.h +++ b/lib/symboldatabase.h @@ -1320,7 +1320,7 @@ public: debugPath() {} - static ValueType parseDecl(const Token *type, const Settings *settings); + static ValueType parseDecl(const Token *type, const Settings *settings, bool isCpp); static Type typeFromString(const std::string &typestr, bool longType); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 1f8e5ad17..158d2b7c0 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -452,7 +452,7 @@ static std::vector getParentValueTypes(const Token* tok, const ValueType* vtCont = contTok->valueType(); if (!vtCont->containerTypeToken) return {}; - ValueType vtParent = ValueType::parseDecl(vtCont->containerTypeToken, settings); + ValueType vtParent = ValueType::parseDecl(vtCont->containerTypeToken, settings, true); // TODO: set isCpp return {std::move(vtParent)}; } if (Token::Match(tok->astParent(), "return|(|{|%assign%") && parent) { @@ -807,7 +807,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); + const ValueType &valueType = ValueType::parseDecl(castType, settings, true); // TODO: set isCpp 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)) @@ -1108,7 +1108,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); + const ValueType &valueType = ValueType::parseDecl(typeTok, settings, true); // TODO: set isCpp if (valueType.pointer > 0) return settings->sizeof_pointer; if (valueType.type == ValueType::Type::BOOL || valueType.type == ValueType::Type::CHAR) @@ -1323,7 +1323,7 @@ static Token * valueFlowSetConstantValue(Token *tok, const Settings *settings, b setTokenValue(tok->next(), value, settings); } } else if (!tok2->type()) { - const ValueType& vt = ValueType::parseDecl(tok2, settings); + const ValueType& vt = ValueType::parseDecl(tok2, settings, true); // TODO: set isCpp size_t sz = ValueFlow::getSizeOf(vt, settings); const Token* brac = tok2->astParent(); while (Token::simpleMatch(brac, "[")) { @@ -4670,7 +4670,7 @@ static void valueFlowLifetime(TokenList *tokenlist, SymbolDatabase*, ErrorLogger bool isContainerOfPointers = true; const Token* containerTypeToken = tok->valueType()->containerTypeToken; if (containerTypeToken) { - ValueType vt = ValueType::parseDecl(containerTypeToken, settings); + ValueType vt = ValueType::parseDecl(containerTypeToken, settings, true); // TODO: set isCpp isContainerOfPointers = vt.pointer > 0; } @@ -8050,7 +8050,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); + ValueType vt = ValueType::parseDecl(containerTypeToken, settings, true); // TODO: set isCpp if (vt.pointer > 0 && astIsPointer(args[0])) initList = true; else if (vt.type == ValueType::ITERATOR && astIsIterator(args[0])) @@ -8434,7 +8434,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); + const ValueType &vt = ValueType::parseDecl(typeTokens.front(), settings, true); // TODO: set isCpp return getMinMaxValues(&vt, *settings, minvalue, maxvalue); }