Revert "Skip forwarding values for unique expressions (#5103)"

This reverts commit 26ed052e8d.
This commit is contained in:
Daniel Marjamäki 2023-06-06 17:31:24 +02:00
parent 26ed052e8d
commit 7d4472616b
8 changed files with 16 additions and 89 deletions

View File

@ -181,9 +181,6 @@ struct Analyzer {
virtual void assume(const Token* tok, bool state, unsigned int flags = 0) = 0;
/// Return analyzer for expression at token
virtual ValuePtr<Analyzer> reanalyze(Token* tok, const std::string& msg = emptyString) const = 0;
virtual bool invalid() const {
return false;
}
virtual ~Analyzer() {}
Analyzer(const Analyzer&) = default;
protected:

View File

@ -894,8 +894,6 @@ struct ForwardTraversal {
Analyzer::Result valueFlowGenericForward(Token* start, const Token* end, const ValuePtr<Analyzer>& a, const Settings& settings)
{
if (a->invalid())
return Analyzer::Result{Analyzer::Action::None, Analyzer::Terminate::Bail};
ForwardTraversal ft{a, settings};
ft.updateRange(start, end);
return Analyzer::Result{ ft.actions, ft.terminate };
@ -905,8 +903,6 @@ Analyzer::Result valueFlowGenericForward(Token* start, const ValuePtr<Analyzer>&
{
if (Settings::terminated())
throw TerminateException();
if (a->invalid())
return Analyzer::Result{Analyzer::Action::None, Analyzer::Terminate::Bail};
ForwardTraversal ft{a, settings};
ft.updateRecursive(start);
return Analyzer::Result{ ft.actions, ft.terminate };

View File

@ -390,8 +390,6 @@ struct ReverseTraversal {
void valueFlowGenericReverse(Token* start, const Token* end, const ValuePtr<Analyzer>& a, const Settings& settings)
{
if (a->invalid())
return;
ReverseTraversal rt{a, settings};
rt.traverse(start, end);
}

View File

@ -1625,7 +1625,7 @@ void SymbolDatabase::createSymbolDatabaseExprIds()
exprs[tok->str()].push_back(tok);
tok->exprId(id++);
if (id == std::numeric_limits<nonneg int>::max() / 4) {
if (id == std::numeric_limits<nonneg int>::max()) {
throw InternalError(nullptr, "Ran out of expression ids.", InternalError::INTERNAL);
}
} else if (isCPP() && Token::simpleMatch(tok, "this")) {
@ -1653,27 +1653,6 @@ void SymbolDatabase::createSymbolDatabaseExprIds()
}
}
}
// Mark expressions that are unique
std::unordered_map<nonneg int, Token*> exprMap;
for (Token* tok = const_cast<Token*>(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
if (tok->exprId() == 0)
continue;
auto p = exprMap.emplace(tok->exprId(), tok);
// Already exists so set it to null
if (!p.second) {
p.first->second = nullptr;
}
}
for (const auto& p : exprMap) {
if (!p.second)
continue;
if (p.second->variable()) {
const Variable* var = p.second->variable();
if (var->nameToken() != p.second)
continue;
}
p.second->setUniqueExprId();
}
}
}

View File

@ -901,20 +901,6 @@ public:
mImpl->mExprId = id;
}
void setUniqueExprId()
{
assert(mImpl->mExprId > 0);
mImpl->mExprId |= 1 << efIsUnique;
}
bool isUniqueExprId() const
{
if (mImpl->mExprId > 0) {
return (mImpl->mExprId & (1 << efIsUnique)) != 0;
}
return false;
}
/**
* For debugging purposes, prints token and all tokens
* followed by it.
@ -1341,11 +1327,6 @@ private:
fIsFinalType = (1ULL << 40), // Is this a type with final specifier
};
enum : uint64_t {
efMaxSize = sizeof(nonneg int) * 8,
efIsUnique = efMaxSize - 2,
};
Token::Type mTokType;
uint64_t mFlags;

View File

@ -2438,6 +2438,10 @@ struct ValueFlowAnalyzer : Analyzer {
return false;
}
virtual bool invalid() const {
return false;
}
bool isCPP() const {
return tokenlist->isCPP();
}
@ -3130,20 +3134,11 @@ struct ExpressionAnalyzer : SingleValueFlowAnalyzer {
bool local;
bool unknown;
bool dependOnThis;
bool uniqueExprId;
ExpressionAnalyzer()
: SingleValueFlowAnalyzer(), expr(nullptr), local(true), unknown(false), dependOnThis(false), uniqueExprId(false)
{}
ExpressionAnalyzer() : SingleValueFlowAnalyzer(), expr(nullptr), local(true), unknown(false), dependOnThis(false) {}
ExpressionAnalyzer(const Token* e, ValueFlow::Value val, const TokenList* t, const Settings* s)
: SingleValueFlowAnalyzer(std::move(val), t, s),
expr(e),
local(true),
unknown(false),
dependOnThis(false),
uniqueExprId(false)
{
: SingleValueFlowAnalyzer(std::move(val), t, s), expr(e), local(true), unknown(false), dependOnThis(false) {
assert(e && e->exprId() != 0 && "Not a valid expression");
dependOnThis = exprDependsOnThis(expr);
@ -3152,8 +3147,6 @@ struct ExpressionAnalyzer : SingleValueFlowAnalyzer {
dependOnThis |= exprDependsOnThis(value.tokvalue);
setupExprVarIds(value.tokvalue);
}
uniqueExprId =
expr->isUniqueExprId() && (Token::Match(expr, "%cop%") || !isVariableChanged(expr, 0, s, t->isCPP()));
}
static bool nonLocal(const Variable* var, bool deref) {
@ -3203,13 +3196,7 @@ struct ExpressionAnalyzer : SingleValueFlowAnalyzer {
});
}
virtual bool skipUniqueExprIds() const {
return true;
}
bool invalid() const override {
if (skipUniqueExprIds() && uniqueExprId)
return true;
return unknown;
}
@ -3244,10 +3231,6 @@ struct SameExpressionAnalyzer : ExpressionAnalyzer {
: ExpressionAnalyzer(e, std::move(val), t, s)
{}
bool skipUniqueExprIds() const override {
return false;
}
bool match(const Token* tok) const override
{
return isSameExpression(isCPP(), true, expr, tok, getSettings()->library, true, true);
@ -3263,10 +3246,6 @@ struct OppositeExpressionAnalyzer : ExpressionAnalyzer {
: ExpressionAnalyzer(e, std::move(val), t, s), isNot(pIsNot)
{}
bool skipUniqueExprIds() const override {
return false;
}
bool match(const Token* tok) const override {
return isOppositeCond(isNot, isCPP(), expr, tok, getSettings()->library, true, true);
}

View File

@ -1602,9 +1602,7 @@ private:
"}";
checkSimplifyTypedef(code);
ASSERT_EQUALS_WITHOUT_LINENUMBERS(
"[test.cpp:3]: (debug) valueflow.cpp:6541:(valueFlow) bailout: valueFlowAfterCondition: bailing in conditional block\n",
errout.str());
ASSERT_EQUALS("", errout.str());
}
void simplifyTypedef46() {

View File

@ -3749,15 +3749,14 @@ private:
" return x + y + a.y + b.y;\n"
"}\n");
const char expected[] =
"1: struct A {\n"
"2: int x ; int y ;\n"
"3: } ;\n"
"4: int f ( A a , A b ) {\n"
"5: int x@5 ; x@5 =@9 a@3 .@10 x@6 +@11 b@4 .@12 x@7 ;\n"
"6: int y@8 ; y@8 =@1073741837 b@4 .@12 x@7 +@11 a@3 .@10 x@6 ;\n"
"7: return x@5 +@1073741841 y@8 +@1073741842 a@3 .@1073741843 y@9 +@1073741844 b@4 .@1073741845 y@10 ;\n"
"8: }\n";
const char expected[] = "1: struct A {\n"
"2: int x ; int y ;\n"
"3: } ;\n"
"4: int f ( A a , A b ) {\n"
"5: int x@5 ; x@5 =@9 a@3 .@10 x@6 +@11 b@4 .@12 x@7 ;\n"
"6: int y@8 ; y@8 =@13 b@4 .@12 x@7 +@11 a@3 .@10 x@6 ;\n"
"7: return x@5 +@17 y@8 +@18 a@3 .@19 y@9 +@20 b@4 .@21 y@10 ;\n"
"8: }\n";
ASSERT_EQUALS(expected, actual);
}