fixes #11104 (avoid C++-only parsing when processing C code in parsedecl()) / also avoid remaining `Library::detect*()` calls (#5346)
This commit is contained in:
parent
41bdd87d30
commit
a92b10ca3b
|
@ -738,7 +738,7 @@ std::vector<ValueType> getParentValueTypes(const Token* tok, const Settings* set
|
||||||
const ValueType* vtCont = contTok->valueType();
|
const ValueType* vtCont = contTok->valueType();
|
||||||
if (!vtCont->containerTypeToken)
|
if (!vtCont->containerTypeToken)
|
||||||
return {};
|
return {};
|
||||||
ValueType vtParent = ValueType::parseDecl(vtCont->containerTypeToken, *settings, true); // TODO: set isCpp
|
ValueType vtParent = ValueType::parseDecl(vtCont->containerTypeToken, *settings);
|
||||||
return {std::move(vtParent)};
|
return {std::move(vtParent)};
|
||||||
}
|
}
|
||||||
if (Token::Match(tok->astParent(), "return|(|{|%assign%") && parent) {
|
if (Token::Match(tok->astParent(), "return|(|{|%assign%") && parent) {
|
||||||
|
|
|
@ -3228,7 +3228,7 @@ void CheckClass::checkThisUseAfterFree()
|
||||||
for (const Variable &var : classScope->varlist) {
|
for (const Variable &var : classScope->varlist) {
|
||||||
// Find possible "self pointer".. pointer/smartpointer member variable of "self" type.
|
// Find possible "self pointer".. pointer/smartpointer member variable of "self" type.
|
||||||
if (var.valueType() && var.valueType()->smartPointerType != classScope->definedType && var.valueType()->typeScope != classScope) {
|
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)
|
if (valueType.smartPointerType != classScope->definedType)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -437,7 +437,7 @@ void CheckType::checkFloatToIntegerOverflow()
|
||||||
while (scope && scope->type != Scope::ScopeType::eLambda && scope->type != Scope::ScopeType::eFunction)
|
while (scope && scope->type != Scope::ScopeType::eLambda && scope->type != Scope::ScopeType::eFunction)
|
||||||
scope = scope->nestedIn;
|
scope = scope->nestedIn;
|
||||||
if (scope && scope->type == Scope::ScopeType::eFunction && scope->function && scope->function->retDef) {
|
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();
|
vtfloat = tok->astOperand1()->valueType();
|
||||||
checkFloatToIntegerOverflow(tok, &valueType, vtfloat, tok->astOperand1()->values());
|
checkFloatToIntegerOverflow(tok, &valueType, vtfloat, tok->astOperand1()->values());
|
||||||
}
|
}
|
||||||
|
|
|
@ -630,7 +630,7 @@ void clangimport::AstNode::setValueType(Token *tok)
|
||||||
if (!decl.front())
|
if (!decl.front())
|
||||||
break;
|
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) {
|
if (valueType.type != ValueType::Type::UNKNOWN_TYPE) {
|
||||||
tok->setValueType(new ValueType(valueType));
|
tok->setValueType(new ValueType(valueType));
|
||||||
break;
|
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()) {
|
for (Token *tok = const_cast<Token*>(tokenizer->tokens()); tok; tok = tok->next()) {
|
||||||
if (Token::simpleMatch(tok, "sizeof (")) {
|
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);
|
const int sz = vt.typeSize(settings->platform, true);
|
||||||
if (sz <= 0)
|
if (sz <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -2214,12 +2214,13 @@ void Variable::evaluate(const Settings* settings)
|
||||||
|
|
||||||
const Library * const lib = &settings->library;
|
const Library * const lib = &settings->library;
|
||||||
|
|
||||||
|
// TODO: ValueType::parseDecl() is also performing a container lookup
|
||||||
bool isContainer = false;
|
bool isContainer = false;
|
||||||
if (mNameToken)
|
if (mNameToken)
|
||||||
setFlag(fIsArray, arrayDimensions(settings, isContainer));
|
setFlag(fIsArray, arrayDimensions(settings, isContainer));
|
||||||
|
|
||||||
if (mTypeStartToken)
|
if (mTypeStartToken)
|
||||||
setValueType(ValueType::parseDecl(mTypeStartToken,*settings, true)); // TODO: set isCpp
|
setValueType(ValueType::parseDecl(mTypeStartToken,*settings));
|
||||||
|
|
||||||
const Token* tok = mTypeStartToken;
|
const Token* tok = mTypeStartToken;
|
||||||
while (tok && tok->previous() && tok->previous()->isName())
|
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(fIsClass, !lib->podtype(strtype) && !mTypeStartToken->isStandardType() && !isEnumType() && !isPointer() && !isReference() && strtype != "...");
|
||||||
setFlag(fIsStlType, Token::simpleMatch(mTypeStartToken, "std ::"));
|
setFlag(fIsStlType, Token::simpleMatch(mTypeStartToken, "std ::"));
|
||||||
setFlag(fIsStlString, ::isStlStringType(mTypeStartToken));
|
setFlag(fIsStlString, ::isStlStringType(mTypeStartToken));
|
||||||
setFlag(fIsSmartPointer, lib->isSmartPointer(mTypeStartToken));
|
setFlag(fIsSmartPointer, mTypeStartToken->isCpp() && lib->isSmartPointer(mTypeStartToken));
|
||||||
}
|
}
|
||||||
if (mAccess == AccessControl::Argument) {
|
if (mAccess == AccessControl::Argument) {
|
||||||
tok = mNameToken;
|
tok = mNameToken;
|
||||||
|
@ -3558,7 +3559,7 @@ bool Type::isDerivedFrom(const std::string & ancestor) const
|
||||||
bool Variable::arrayDimensions(const Settings* settings, bool& isContainer)
|
bool Variable::arrayDimensions(const Settings* settings, bool& isContainer)
|
||||||
{
|
{
|
||||||
isContainer = false;
|
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) {
|
if (container && container->arrayLike_indexOp && container->size_templateArgNo > 0) {
|
||||||
const Token* tok = Token::findsimplematch(mTypeStartToken, "<");
|
const Token* tok = Token::findsimplematch(mTypeStartToken, "<");
|
||||||
if (tok) {
|
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);
|
return tok1->valueType()->typeScope->findFunction(tok, tok1->valueType()->constness == 1);
|
||||||
if (tok1 && Token::Match(tok1->previous(), "%name% (") && tok1->previous()->function() &&
|
if (tok1 && Token::Match(tok1->previous(), "%name% (") && tok1->previous()->function() &&
|
||||||
tok1->previous()->function()->retDef) {
|
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)
|
if (vt.typeScope)
|
||||||
return vt.typeScope->findFunction(tok, vt.constness == 1);
|
return vt.typeScope->findFunction(tok, vt.constness == 1);
|
||||||
} else if (Token::Match(tok1, "%var% .")) {
|
} 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(), "(")) {
|
} else if (Token::simpleMatch(tok->previous()->astOperand1(), "(")) {
|
||||||
const Token *castTok = tok->previous()->astOperand1();
|
const Token *castTok = tok->previous()->astOperand1();
|
||||||
if (castTok->isCast()) {
|
if (castTok->isCast()) {
|
||||||
ValueType vt = ValueType::parseDecl(castTok->next(),mSettings, mIsCpp);
|
ValueType vt = ValueType::parseDecl(castTok->next(),mSettings);
|
||||||
if (vt.typeScope)
|
if (vt.typeScope)
|
||||||
return vt.typeScope->findFunction(tok, vt.constness == 1);
|
return vt.typeScope->findFunction(tok, vt.constness == 1);
|
||||||
}
|
}
|
||||||
|
@ -5697,7 +5698,7 @@ const Function* SymbolDatabase::findFunction(const Token* const tok) const
|
||||||
}
|
}
|
||||||
// Check for constructor
|
// Check for constructor
|
||||||
if (Token::Match(tok, "%name% (|{")) {
|
if (Token::Match(tok, "%name% (|{")) {
|
||||||
ValueType vt = ValueType::parseDecl(tok, mSettings, mIsCpp);
|
ValueType vt = ValueType::parseDecl(tok, mSettings);
|
||||||
if (vt.typeScope)
|
if (vt.typeScope)
|
||||||
return vt.typeScope->findFunction(tok, false);
|
return vt.typeScope->findFunction(tok, false);
|
||||||
}
|
}
|
||||||
|
@ -6991,7 +6992,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
|
||||||
}
|
}
|
||||||
|
|
||||||
// Construct smart pointer
|
// Construct smart pointer
|
||||||
else if (mSettings.library.isSmartPointer(start)) {
|
else if (mIsCpp && mSettings.library.isSmartPointer(start)) {
|
||||||
ValueType valuetype;
|
ValueType valuetype;
|
||||||
if (parsedecl(start, &valuetype, mDefaultSignedness, mSettings, mIsCpp)) {
|
if (parsedecl(start, &valuetype, mDefaultSignedness, mSettings, mIsCpp)) {
|
||||||
setValueType(tok, valuetype);
|
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();
|
const Token *typeStartToken = tok->astOperand1();
|
||||||
while (typeStartToken && typeStartToken->str() == "::")
|
while (typeStartToken && typeStartToken->str() == "::")
|
||||||
typeStartToken = typeStartToken->astOperand1();
|
typeStartToken = typeStartToken->astOperand1();
|
||||||
|
@ -7216,7 +7217,7 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
|
||||||
functionScope = functionScope->nestedIn;
|
functionScope = functionScope->nestedIn;
|
||||||
if (functionScope && functionScope->type == Scope::eFunction && functionScope->function &&
|
if (functionScope && functionScope->type == Scope::eFunction && functionScope->function &&
|
||||||
functionScope->function->retDef) {
|
functionScope->function->retDef) {
|
||||||
ValueType vt = ValueType::parseDecl(functionScope->function->retDef, mSettings, mIsCpp);
|
ValueType vt = ValueType::parseDecl(functionScope->function->retDef, mSettings);
|
||||||
setValueType(tok, vt);
|
setValueType(tok, vt);
|
||||||
if (Token::simpleMatch(tok, "return {"))
|
if (Token::simpleMatch(tok, "return {"))
|
||||||
setValueType(tok->next(), vt);
|
setValueType(tok->next(), vt);
|
||||||
|
@ -7314,10 +7315,10 @@ void SymbolDatabase::setValueTypeInTokenList(bool reportDebugWarnings, Token *to
|
||||||
createSymbolDatabaseSetVariablePointers();
|
createSymbolDatabaseSetVariablePointers();
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType ValueType::parseDecl(const Token *type, const Settings &settings, bool isCpp)
|
ValueType ValueType::parseDecl(const Token *type, const Settings &settings)
|
||||||
{
|
{
|
||||||
ValueType vt;
|
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;
|
return vt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1268,7 +1268,7 @@ public:
|
||||||
originalTypeName(std::move(otn))
|
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);
|
static Type typeFromString(const std::string &typestr, bool longType);
|
||||||
|
|
||||||
|
|
|
@ -2586,3 +2586,11 @@ Token* findLambdaEndScope(Token* tok)
|
||||||
const Token* findLambdaEndScope(const Token* tok) {
|
const Token* findLambdaEndScope(const Token* tok) {
|
||||||
return findLambdaEndScope(const_cast<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
|
||||||
|
}
|
||||||
|
|
|
@ -1484,6 +1484,9 @@ public:
|
||||||
void setTokenDebug(TokenDebug td) {
|
void setTokenDebug(TokenDebug td) {
|
||||||
mImpl->mDebug = td;
|
mImpl->mDebug = td;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** defaults to C++ if it cannot be determined */
|
||||||
|
bool isCpp() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
Token* findTypeEnd(Token* tok);
|
Token* findTypeEnd(Token* tok);
|
||||||
|
|
|
@ -760,7 +760,7 @@ static void setTokenValue(Token* tok,
|
||||||
if (contains({ValueFlow::Value::ValueType::INT, ValueFlow::Value::ValueType::SYMBOLIC}, value.valueType) &&
|
if (contains({ValueFlow::Value::ValueType::INT, ValueFlow::Value::ValueType::SYMBOLIC}, value.valueType) &&
|
||||||
Token::simpleMatch(parent->astOperand1(), "dynamic_cast"))
|
Token::simpleMatch(parent->astOperand1(), "dynamic_cast"))
|
||||||
return;
|
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) &&
|
if (value.isImpossible() && value.isIntValue() && value.intvalue < 0 && astIsUnsigned(tok) &&
|
||||||
valueType.sign == ValueType::SIGNED && tok->valueType() &&
|
valueType.sign == ValueType::SIGNED && tok->valueType() &&
|
||||||
ValueFlow::getSizeOf(*tok->valueType(), settings) >= ValueFlow::getSizeOf(valueType, settings))
|
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)
|
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);
|
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);
|
setTokenValue(tok->next(), std::move(value), settings);
|
||||||
}
|
}
|
||||||
} else if (!tok2->type()) {
|
} 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);
|
size_t sz = ValueFlow::getSizeOf(vt, settings);
|
||||||
const Token* brac = tok2->astParent();
|
const Token* brac = tok2->astParent();
|
||||||
while (Token::simpleMatch(brac, "[")) {
|
while (Token::simpleMatch(brac, "[")) {
|
||||||
|
@ -4765,7 +4765,7 @@ static bool isContainerOfPointers(const Token* tok, const Settings* settings)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ValueType vt = ValueType::parseDecl(tok, *settings, true); // TODO: set isCpp
|
ValueType vt = ValueType::parseDecl(tok, *settings);
|
||||||
return vt.pointer > 0;
|
return vt.pointer > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8628,7 +8628,7 @@ static bool valueFlowIsSameContainerType(const ValueType& contType, const Token*
|
||||||
if (!tok || !tok->valueType() || !tok->valueType()->containerTypeToken)
|
if (!tok || !tok->valueType() || !tok->valueType()->containerTypeToken)
|
||||||
return false;
|
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);
|
return contType.isTypeEqual(&tokType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8648,7 +8648,7 @@ static std::vector<ValueFlow::Value> getInitListSize(const Token* tok,
|
||||||
if (valueType->container->stdStringLike) {
|
if (valueType->container->stdStringLike) {
|
||||||
initList = astIsGenericChar(args[0]) && !astIsPointer(args[0]);
|
initList = astIsGenericChar(args[0]) && !astIsPointer(args[0]);
|
||||||
} else if (containerTypeToken && settings) {
|
} 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]))
|
if (vt.pointer > 0 && astIsPointer(args[0]))
|
||||||
initList = true;
|
initList = true;
|
||||||
else if (vt.type == ValueType::ITERATOR && astIsIterator(args[0]))
|
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;
|
return false;
|
||||||
typeTokens.simplifyPlatformTypes();
|
typeTokens.simplifyPlatformTypes();
|
||||||
typeTokens.simplifyStdType();
|
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);
|
return getMinMaxValues(&vt, settings->platform, minvalue, maxvalue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue