fixes #11104 (avoid C++-only parsing when processing C code in parsedecl()) / also avoid remaining `Library::detect*()` calls (#5346)

This commit is contained in:
Oliver Stöneberg 2023-08-18 22:48:24 +02:00 committed by GitHub
parent 41bdd87d30
commit a92b10ca3b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 36 additions and 24 deletions

View File

@ -738,7 +738,7 @@ std::vector<ValueType> 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) {

View File

@ -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;
}

View File

@ -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());
}

View File

@ -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<Token*>(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;

View File

@ -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;
}

View File

@ -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);

View File

@ -2586,3 +2586,11 @@ Token* findLambdaEndScope(Token* tok)
const Token* findLambdaEndScope(const Token* tok) {
return findLambdaEndScope(const_cast<Token*>(tok));
}
bool Token::isCpp() const
{
if (mTokensFrontBack && mTokensFrontBack->list) {
return mTokensFrontBack->list->isCPP();
}
return true; // assume C++ by default
}

View File

@ -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);

View File

@ -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<ValueFlow::Value> 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);
}