So the valueFlowAfterCondition takes care of a lot of the cases for forwarding the conditional values. We could refactor this to a more generic function that takes two functions:
I use templates here, but function pointers could be used instead if you dont like the templates. So the Condition function would return ConditionValue struct like this:
The Forward function would call valueFlowForward or the valueFlowContainerForward. This way we can reuse the conditional logic for both container sizes and for regular values. Would you guys be interested in such refactoring in cppcheck?
Here is a rough implementation of such a function:
{{{
template<class forward="" condition,="" class="">
static void valueFlowCondition(TokenList tokenlist, SymbolDatabase symboldatabase, ErrorLogger errorLogger, const Settings settings, Condition condition, Forward forward)
{
for (const Scope * scope : symboldatabase->functionScopes) {
std::set<unsigned> aliased;
for (Token* tok = const_cast<token*>(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
if (Token::Match(tok, "= & %var% ;"))
aliased.insert(tok->tokAt(2)->varId());</token*></unsigned></class>
Hi,
So the valueFlowAfterCondition takes care of a lot of the cases for forwarding the conditional values. We could refactor this to a more generic function that takes two functions:
{{{
template<class forward="" condition,="" class="">
static void valueFlowCondition(TokenList tokenlist, SymbolDatabase symboldatabase, ErrorLogger errorLogger, const Settings settings, Condition condition, Forward forward);
}}}</class>
I use templates here, but function pointers could be used instead if you dont like the templates. So the
Condition
function would returnConditionValue
struct like this:{{{
struct ConditionValue
{
std::list<valueflow::value> true_values = {};
std::list<valueflow::value> false_values = {};
const Token * vartok = nullptr;
};
}}}</valueflow::value></valueflow::value>
The
Forward
function would callvalueFlowForward
or thevalueFlowContainerForward
. This way we can reuse the conditional logic for both container sizes and for regular values. Would you guys be interested in such refactoring in cppcheck?Here is a rough implementation of such a function:
{{{
template<class forward="" condition,="" class="">
static void valueFlowCondition(TokenList tokenlist, SymbolDatabase symboldatabase, ErrorLogger errorLogger, const Settings settings, Condition condition, Forward forward)
{
for (const Scope * scope : symboldatabase->functionScopes) {
std::set<unsigned> aliased;
for (Token* tok = const_cast<token*>(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) {
if (Token::Match(tok, "= & %var% ;"))
aliased.insert(tok->tokAt(2)->varId());</token*></unsigned></class>
}
}
}}}