diff --git a/lib/symboldatabase.cpp b/lib/symboldatabase.cpp index 29f7387b06d0..da67db946de6 100644 --- a/lib/symboldatabase.cpp +++ b/lib/symboldatabase.cpp @@ -1581,7 +1581,7 @@ namespace { } }; using ExprIdMap = std::map; - void setParentExprId(Token* tok, ExprIdMap& exprIdMap, nonneg int &id) { + void setParentExprId(Token* tok, bool cpp, ExprIdMap& exprIdMap, nonneg int &id) { if (!tok->astParent() || tok->astParent()->isControlFlowKeyword()) return; const Token* op1 = tok->astParent()->astOperand1(); @@ -1591,10 +1591,10 @@ namespace { if (op2 && op2->exprId() == 0) return; - if (tok->astParent()->isExpandedMacro()) { + if (tok->astParent()->isExpandedMacro() || Token::Match(tok->astParent(), "++|--")) { tok->astParent()->exprId(id); ++id; - setParentExprId(tok->astParent(), exprIdMap, id); + setParentExprId(tok->astParent(), cpp, exprIdMap, id); return; } @@ -1612,10 +1612,12 @@ namespace { if (key.operand1 > key.operand2 && key.operand2 && Token::Match(tok->astParent(), "%or%|%oror%|+|*|&|&&|^|==|!=")) { // In C++ the order of operands of + might matter - if (key.parentOp != "+" || - !tok->astParent()->valueType() || - tok->astParent()->valueType()->isIntegral() || - tok->astParent()->valueType()->isFloat()) + if (!cpp || + key.parentOp != "+" || + !tok->astParent()->valueType() || + tok->astParent()->valueType()->isIntegral() || + tok->astParent()->valueType()->isFloat() || + tok->astParent()->valueType()->pointer > 0) std::swap(key.operand1, key.operand2); } @@ -1630,7 +1632,7 @@ namespace { } else { tok->astParent()->exprId(it->second); } - setParentExprId(tok->astParent(), exprIdMap, id); + setParentExprId(tok->astParent(), cpp, exprIdMap, id); i1 = 1 + refs1.size(); break; } @@ -1709,7 +1711,7 @@ void SymbolDatabase::createSymbolDatabaseExprIds() if (tok->varId() > 0) { tok->exprId(tok->varId()); if (tok->astParent() && tok->astParent()->exprId() == 0) - setParentExprId(tok, exprIdMap, id); + setParentExprId(tok, mTokenizer.isCPP(), exprIdMap, id); } else if (tok->astParent() && !tok->astOperand1() && !tok->astOperand2()) { if (tok->tokType() == Token::Type::eBracket) continue; @@ -1732,7 +1734,7 @@ void SymbolDatabase::createSymbolDatabaseExprIds() } } - setParentExprId(tok, exprIdMap, id); + setParentExprId(tok, mTokenizer.isCPP(), exprIdMap, id); } } for (Token* tok = const_cast(scope->bodyStart); tok != scope->bodyEnd; tok = tok->next()) { diff --git a/test/testvarid.cpp b/test/testvarid.cpp index 8182669d414a..2f33d556f7f6 100644 --- a/test/testvarid.cpp +++ b/test/testvarid.cpp @@ -240,6 +240,7 @@ class TestVarID : public TestFixture { TEST_CASE(exprid3); TEST_CASE(exprid4); TEST_CASE(exprid5); + TEST_CASE(exprid6); TEST_CASE(structuredBindings); } @@ -3929,6 +3930,19 @@ class TestVarID : public TestFixture { ASSERT_EQUALS(expected, tokenizeExpr(code)); } + void exprid6() { + // ++ and -- should have UNIQUE exprid + const char code[] = "void foo(int *a) {\n" + " *a++ = 0;\n" + " if (*a++ == 32) {}\n" + "}\n"; + const char expected[] = "1: void foo ( int * a ) {\n" + "2: *@UNIQUE a@1 ++@UNIQUE = 0 ;\n" + "3: if ( *@UNIQUE a@1 ++@UNIQUE ==@UNIQUE 32 ) { }\n" + "4: }\n"; + ASSERT_EQUALS(expected, tokenizeExpr(code)); + } + void structuredBindings() { const char code[] = "int foo() { auto [x,y] = xy(); return x+y; }"; ASSERT_EQUALS("1: int foo ( ) { auto [ x@1 , y@2 ] = xy ( ) ; return x@1 + y@2 ; }\n",