Skip to content

Commit

Permalink
fixes #11104 (avoid C++-only parsing when processing C code in parsed…
Browse files Browse the repository at this point in the history
…ecl()) / also avoid remaining `Library::detect*()` calls (danmar#5346)
  • Loading branch information
firewave authored Aug 18, 2023
1 parent 41bdd87 commit a92b10c
Show file tree
Hide file tree
Showing 9 changed files with 36 additions and 24 deletions.
2 changes: 1 addition & 1 deletion lib/astutils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 1 addition & 1 deletion lib/checkclass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion lib/checktype.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand Down
4 changes: 2 additions & 2 deletions lib/clangimport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
23 changes: 12 additions & 11 deletions lib/symboldatabase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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% .")) {
Expand All @@ -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);
}
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down
2 changes: 1 addition & 1 deletion lib/symboldatabase.h
Original file line number Diff line number Diff line change
Expand Up @@ -1268,7 +1268,7 @@ class CPPCHECKLIB ValueType {
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);

Expand Down
8 changes: 8 additions & 0 deletions lib/token.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
3 changes: 3 additions & 0 deletions lib/token.h
Original file line number Diff line number Diff line change
Expand Up @@ -1484,6 +1484,9 @@ class CPPCHECKLIB Token {
void setTokenDebug(TokenDebug td) {
mImpl->mDebug = td;
}

/** defaults to C++ if it cannot be determined */
bool isCpp() const;
};

Token* findTypeEnd(Token* tok);
Expand Down
14 changes: 7 additions & 7 deletions lib/valueflow.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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);
}
Expand Down Expand Up @@ -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, "[")) {
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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);
}

Expand All @@ -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]))
Expand Down Expand Up @@ -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);
}

Expand Down

0 comments on commit a92b10c

Please sign in to comment.