@@ -335,20 +335,6 @@ const Token *ValueFlow::parseCompareInt(const Token *tok, ValueFlow::Value &true
335335 });
336336}
337337
338- static bool isEscapeScope (const Token* tok, const Settings& settings, bool unknown = false )
339- {
340- if (!Token::simpleMatch (tok, " {" ))
341- return false ;
342- // TODO this search for termTok in all subscopes. It should check the end of the scope.
343- const Token * termTok = Token::findmatch (tok, " return|continue|break|throw|goto" , tok->link ());
344- if (termTok && termTok->scope () == tok->scope ())
345- return true ;
346- std::string unknownFunction;
347- if (settings.library .isScopeNoReturn (tok->link (), &unknownFunction))
348- return unknownFunction.empty () || unknown;
349- return false ;
350- }
351-
352338void ValueFlow::combineValueProperties (const ValueFlow::Value &value1, const ValueFlow::Value &value2, ValueFlow::Value &result)
353339{
354340 if (value1.isKnown () && value2.isKnown ())
@@ -2479,167 +2465,6 @@ static void valueFlowAfterMove(const TokenList& tokenlist, const SymbolDatabase&
24792465 }
24802466}
24812467
2482- static const Token* findIncompleteVar (const Token* start, const Token* end)
2483- {
2484- for (const Token* tok = start; tok != end; tok = tok->next ()) {
2485- if (tok->isIncompleteVar ())
2486- return tok;
2487- }
2488- return nullptr ;
2489- }
2490-
2491- static ValueFlow::Value makeConditionValue (long long val,
2492- const Token* condTok,
2493- bool assume,
2494- bool impossible,
2495- const Settings& settings,
2496- SourceLocation loc = SourceLocation::current())
2497- {
2498- ValueFlow::Value v (val);
2499- v.setKnown ();
2500- if (impossible) {
2501- v.intvalue = !v.intvalue ;
2502- v.setImpossible ();
2503- }
2504- v.condition = condTok;
2505- if (assume)
2506- v.errorPath .emplace_back (condTok, " Assuming condition '" + condTok->expressionString () + " ' is true" );
2507- else
2508- v.errorPath .emplace_back (condTok, " Assuming condition '" + condTok->expressionString () + " ' is false" );
2509- if (settings.debugnormal )
2510- setSourceLocation (v, loc, condTok);
2511- return v;
2512- }
2513-
2514- static std::vector<const Token*> getConditions (const Token* tok, const char * op)
2515- {
2516- std::vector<const Token*> conds = {tok};
2517- if (tok->str () == op) {
2518- std::vector<const Token*> args = astFlatten (tok, op);
2519- std::copy_if (args.cbegin (), args.cend (), std::back_inserter (conds), [&](const Token* tok2) {
2520- if (tok2->exprId () == 0 )
2521- return false ;
2522- if (tok2->hasKnownIntValue ())
2523- return false ;
2524- if (Token::Match (tok2, " %var%|." ) && !astIsBool (tok2))
2525- return false ;
2526- return true ;
2527- });
2528- }
2529- return conds;
2530- }
2531-
2532- static bool isBreakOrContinueScope (const Token* endToken)
2533- {
2534- if (!Token::simpleMatch (endToken, " }" ))
2535- return false ;
2536- return Token::Match (endToken->tokAt (-2 ), " break|continue ;" );
2537- }
2538-
2539- static const Scope* getLoopScope (const Token* tok)
2540- {
2541- if (!tok)
2542- return nullptr ;
2543- const Scope* scope = tok->scope ();
2544- while (scope && scope->type != Scope::eWhile && scope->type != Scope::eFor && scope->type != Scope::eDo)
2545- scope = scope->nestedIn ;
2546- return scope;
2547- }
2548-
2549- //
2550- static void valueFlowConditionExpressions (const TokenList &tokenlist, const SymbolDatabase& symboldatabase, ErrorLogger &errorLogger, const Settings &settings)
2551- {
2552- if (!settings.daca && !settings.vfOptions .doConditionExpressionAnalysis )
2553- {
2554- if (settings.debugwarnings ) {
2555- ErrorMessage::FileLocation loc (tokenlist.getSourceFilePath (), 0 , 0 );
2556- const ErrorMessage errmsg ({std::move (loc)}, tokenlist.getSourceFilePath (), Severity::debug, " Analysis of condition expressions is disabled. Use --check-level=exhaustive to enable it." , " normalCheckLevelConditionExpressions" , Certainty::normal);
2557- errorLogger.reportErr (errmsg);
2558- }
2559- return ;
2560- }
2561-
2562- for (const Scope * scope : symboldatabase.functionScopes ) {
2563- if (const Token* incompleteTok = findIncompleteVar (scope->bodyStart , scope->bodyEnd )) {
2564- if (settings.debugwarnings )
2565- bailoutIncompleteVar (tokenlist, errorLogger, incompleteTok, " Skipping function due to incomplete variable " + incompleteTok->str ());
2566- continue ;
2567- }
2568-
2569- if (settings.daca && !settings.vfOptions .doConditionExpressionAnalysis )
2570- continue ;
2571-
2572- for (auto * tok = const_cast <Token*>(scope->bodyStart ); tok != scope->bodyEnd ; tok = tok->next ()) {
2573- if (!Token::simpleMatch (tok, " if (" ))
2574- continue ;
2575- Token* parenTok = tok->next ();
2576- if (!Token::simpleMatch (parenTok->link (), " ) {" ))
2577- continue ;
2578- Token * blockTok = parenTok->link ()->tokAt (1 );
2579- const Token* condTok = parenTok->astOperand2 ();
2580- if (condTok->exprId () == 0 )
2581- continue ;
2582- if (condTok->hasKnownIntValue ())
2583- continue ;
2584- if (!isConstExpression (condTok, settings.library ))
2585- continue ;
2586- const bool isOp = condTok->isComparisonOp () || condTok->tokType () == Token::eLogicalOp;
2587- const bool is1 = isOp || astIsBool (condTok);
2588-
2589- Token* startTok = blockTok;
2590- // Inner condition
2591- {
2592- for (const Token* condTok2 : getConditions (condTok, " &&" )) {
2593- if (is1) {
2594- const bool isBool = astIsBool (condTok2) || Token::Match (condTok2, " %comp%|%oror%|&&" );
2595- auto a1 = makeSameExpressionAnalyzer (condTok2, makeConditionValue (1 , condTok2, /* assume*/ true , !isBool, settings), settings); // don't set '1' for non-boolean expressions
2596- valueFlowGenericForward (startTok, startTok->link (), a1, tokenlist, errorLogger, settings);
2597- }
2598-
2599- auto a2 = makeOppositeExpressionAnalyzer (true , condTok2, makeConditionValue (0 , condTok2, true , false , settings), settings);
2600- valueFlowGenericForward (startTok, startTok->link (), a2, tokenlist, errorLogger, settings);
2601- }
2602- }
2603-
2604- std::vector<const Token*> conds = getConditions (condTok, " ||" );
2605-
2606- // Check else block
2607- if (Token::simpleMatch (startTok->link (), " } else {" )) {
2608- startTok = startTok->link ()->tokAt (2 );
2609- for (const Token* condTok2:conds) {
2610- auto a1 = makeSameExpressionAnalyzer (condTok2, makeConditionValue (0 , condTok2, false , false , settings), settings);
2611- valueFlowGenericForward (startTok, startTok->link (), a1, tokenlist, errorLogger, settings);
2612-
2613- if (is1) {
2614- auto a2 = makeOppositeExpressionAnalyzer (true , condTok2, makeConditionValue (isOp, condTok2, false , false , settings), settings);
2615- valueFlowGenericForward (startTok, startTok->link (), a2, tokenlist, errorLogger, settings);
2616- }
2617- }
2618- }
2619-
2620- // Check if the block terminates early
2621- if (isEscapeScope (blockTok, settings)) {
2622- const Scope* scope2 = scope;
2623- // If escaping a loop then only use the loop scope
2624- if (isBreakOrContinueScope (blockTok->link ())) {
2625- scope2 = getLoopScope (blockTok->link ());
2626- if (!scope2)
2627- continue ;
2628- }
2629- for (const Token* condTok2:conds) {
2630- auto a1 = makeSameExpressionAnalyzer (condTok2, makeConditionValue (0 , condTok2, false , false , settings), settings);
2631- valueFlowGenericForward (startTok->link ()->next (), scope2->bodyEnd , a1, tokenlist, errorLogger, settings);
2632-
2633- if (is1) {
2634- auto a2 = makeOppositeExpressionAnalyzer (true , condTok2, makeConditionValue (1 , condTok2, false , false , settings), settings);
2635- valueFlowGenericForward (startTok->link ()->next (), scope2->bodyEnd , a2, tokenlist, errorLogger, settings);
2636- }
2637- }
2638- }
2639- }
2640- }
2641- }
2642-
26432468static bool isTruncated (const ValueType* src, const ValueType* dst, const Settings& settings)
26442469{
26452470 if (src->pointer > 0 || dst->pointer > 0 )
@@ -3981,8 +3806,8 @@ struct ConditionHandler {
39813806 const bool isKnown = std::any_of (values.cbegin (), values.cend (), [&](const ValueFlow::Value& v) {
39823807 return v.isKnown () || v.isImpossible ();
39833808 });
3984- if (isKnown && isBreakOrContinueScope (after)) {
3985- const Scope* loopScope = getLoopScope (cond.vartok );
3809+ if (isKnown && ValueFlow:: isBreakOrContinueScope (after)) {
3810+ const Scope* loopScope = ValueFlow:: getLoopScope (cond.vartok );
39863811 if (loopScope) {
39873812 Analyzer::Result r = forward (after, loopScope->bodyEnd , cond.vartok , values, tokenlist, errorLogger, settings);
39883813 if (r.terminate != Analyzer::Terminate::None)
@@ -6009,7 +5834,7 @@ void ValueFlow::setValues(TokenList& tokenlist,
60095834 VFA (valueFlowSymbolic (tokenlist, symboldatabase, errorLogger, settings)),
60105835 VFA (analyzeBitAnd (tokenlist, settings)),
60115836 VFA (analyzeSameExpressions (tokenlist, settings)),
6012- VFA (valueFlowConditionExpressions (tokenlist, symboldatabase, errorLogger, settings)),
5837+ VFA (analyzeConditionExpressions (tokenlist, symboldatabase, errorLogger, settings)),
60135838 });
60145839
60155840 runner.run ({
0 commit comments