diff --git a/lib/programmemory.cpp b/lib/programmemory.cpp index b95a222c0..8aee0791b 100644 --- a/lib/programmemory.cpp +++ b/lib/programmemory.cpp @@ -420,12 +420,12 @@ ProgramMemory getProgramMemory(const Token *tok, const ProgramMemory::Map& vars) return programMemory; } -ProgramMemory getProgramMemory(const Token* tok, nonneg int exprid, const ValueFlow::Value& value) +ProgramMemory getProgramMemory(const Token* tok, nonneg int exprid, const ValueFlow::Value& value, const Settings *settings) { ProgramMemory programMemory; programMemory.replace(getInitialProgramState(tok, value.tokvalue)); programMemory.replace(getInitialProgramState(tok, value.condition)); - fillProgramMemoryFromConditions(programMemory, tok, nullptr); + fillProgramMemoryFromConditions(programMemory, tok, settings); programMemory.setValue(exprid, value); if (value.varId) programMemory.setIntValue(value.varId, value.varvalue); diff --git a/lib/programmemory.h b/lib/programmemory.h index 413d3af01..f7ba8d423 100644 --- a/lib/programmemory.h +++ b/lib/programmemory.h @@ -88,7 +88,7 @@ bool conditionIsTrue(const Token *condition, const ProgramMemory &programMemory) /** * Get program memory by looking backwards from given token. */ -ProgramMemory getProgramMemory(const Token* tok, nonneg int exprid, const ValueFlow::Value& value); +ProgramMemory getProgramMemory(const Token* tok, nonneg int exprid, const ValueFlow::Value& value, const Settings *settings); ProgramMemory getProgramMemory(const Token *tok, const ProgramMemory::Map& vars); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 13d9520cb..95d326768 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -5691,7 +5691,7 @@ static void valueFlowForLoopSimplify(Token * const bodyStart, const nonneg int v } if (Token::Match(tok2, "%oror%|&&")) { - const ProgramMemory programMemory(getProgramMemory(tok2->astTop(), varid, ValueFlow::Value(value))); + const ProgramMemory programMemory(getProgramMemory(tok2->astTop(), varid, ValueFlow::Value(value), settings)); if ((tok2->str() == "&&" && !conditionIsTrue(tok2->astOperand1(), programMemory)) || (tok2->str() == "||" && !conditionIsFalse(tok2->astOperand1(), programMemory))) { // Skip second expression.. @@ -5708,8 +5708,8 @@ static void valueFlowForLoopSimplify(Token * const bodyStart, const nonneg int v } } - if ((tok2->str() == "&&" && conditionIsFalse(tok2->astOperand1(), getProgramMemory(tok2->astTop(), varid, ValueFlow::Value(value)))) || - (tok2->str() == "||" && conditionIsTrue(tok2->astOperand1(), getProgramMemory(tok2->astTop(), varid, ValueFlow::Value(value))))) + if ((tok2->str() == "&&" && conditionIsFalse(tok2->astOperand1(), getProgramMemory(tok2->astTop(), varid, ValueFlow::Value(value), settings))) || + (tok2->str() == "||" && conditionIsTrue(tok2->astOperand1(), getProgramMemory(tok2->astTop(), varid, ValueFlow::Value(value), settings)))) break; else if (Token::simpleMatch(tok2, ") {") && Token::findmatch(tok2->link(), "%varid%", tok2, varid)) { diff --git a/test/testvalueflow.cpp b/test/testvalueflow.cpp index 3a9cb9eed..e17c5e725 100644 --- a/test/testvalueflow.cpp +++ b/test/testvalueflow.cpp @@ -3728,6 +3728,19 @@ private: "}"; testValueOfX(code,0,0); // <- don't hang + // crash (daca@home) + code = "void foo(char *z, int n) {\n" + " int i;\n" + " if (fPScript) {\n" + " i = 1;\n" + " } else if (strncmp(&z[n], \"\", 3) == 0) ;\n" + " }\n" + " }\n" + "}"; + testValueOfX(code,0,0); // <- don't crash + // conditional code in loop code = "void f(int mask) {\n" // #6000 " for (int x = 10; x < 14; x++) {\n"