diff --git a/lib/forwardanalyzer.cpp b/lib/forwardanalyzer.cpp index 85a0610ef..7f078a333 100644 --- a/lib/forwardanalyzer.cpp +++ b/lib/forwardanalyzer.cpp @@ -111,8 +111,10 @@ struct ForwardTraversal { return Progress::Skip; T* firstOp = tok->astOperand1(); T* secondOp = tok->astOperand2(); - // Evaluate RHS of assignment before LHS - if (tok->isAssignmentOp()) + // Evaluate: + // 1. RHS of assignment before LHS + // 2. Unary op before operand + if (tok->isAssignmentOp() || !secondOp) std::swap(firstOp, secondOp); if (firstOp && traverseRecursive(firstOp, f, traverseUnknown, recursion+1) == Progress::Break) return Break(); diff --git a/lib/valueflow.cpp b/lib/valueflow.cpp index 42866e137..8d8c497f2 100644 --- a/lib/valueflow.cpp +++ b/lib/valueflow.cpp @@ -1244,7 +1244,7 @@ static void valueFlowPointerAlias(TokenList *tokenlist) } } -static void valueFlowPointerAliasDeref(TokenList *tokenlist) +static void valueFlowUninitPointerAliasDeref(TokenList *tokenlist) { for (Token *tok = tokenlist->front(); tok; tok = tok->next()) { if (!tok->isUnaryOp("*")) @@ -6869,7 +6869,6 @@ void ValueFlow::setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase, while (n > 0 && values < getTotalValues(tokenlist)) { values = getTotalValues(tokenlist); valueFlowImpossibleValues(tokenlist, settings); - valueFlowPointerAliasDeref(tokenlist); valueFlowArrayBool(tokenlist); valueFlowRightShift(tokenlist, settings); valueFlowAfterMove(tokenlist, symboldatabase, errorLogger, settings); @@ -6883,6 +6882,7 @@ void ValueFlow::setValues(TokenList *tokenlist, SymbolDatabase* symboldatabase, valueFlowLifetime(tokenlist, symboldatabase, errorLogger, settings); valueFlowFunctionDefaultParameter(tokenlist, symboldatabase, errorLogger, settings); valueFlowUninit(tokenlist, symboldatabase, errorLogger, settings); + valueFlowUninitPointerAliasDeref(tokenlist); if (tokenlist->isCPP()) { valueFlowSmartPointer(tokenlist, errorLogger, settings); valueFlowIterators(tokenlist, settings); diff --git a/test/teststl.cpp b/test/teststl.cpp index bc522ef80..5059e6162 100644 --- a/test/teststl.cpp +++ b/test/teststl.cpp @@ -440,6 +440,13 @@ private: " (*PArr)[i] = 1;\n" "}\n"); ASSERT_EQUALS("", errout.str()); + + checkNormal("int f() {\n" + " std::vector v;\n" + " std::vector * pv = &v;\n" + " return (*pv).at(42);\n" + "}\n"); + ASSERT_EQUALS("test.cpp:4:error:Out of bounds access in expression '(*pv).at(42)' because '*pv' is empty and 'at' may be non-zero.\n", errout.str()); } void outOfBoundsIndexExpression() {