Repository navigation
Fix #15155 FN accessMoved (string concatenation using +=) - #8996
chrchr-github wants to merge 3 commits into
Conversation
dmcppcheck
left a comment
There was a problem hiding this comment.
AI review
The str().size() == 2 check that detects compound assignment leaves out <<= and >>=, because those operators are 3 characters long. So x <<= 1 / x >>= 1 on a moved object still gets no accessMoved warning, while x += 1 now does. The same gap makes other value types inconsistent: for example, int x; x += y; now gets an uninitvar warning, but int x; x <<= y; stays on legacyUninitvar. Writing it as tok->astParent()->str() != "=" (or Token::Match(parent, "%assign%") && parent->str() != "=") would cover every compound operator.
I found no other new problems. The full testrunner passes. The new nullPointerArithmetic on p += a with a default argument p = 0 matches what base already reports for p + a, so that change makes the two consistent rather than adding a new kind of false positive.
Testing
Built cppcheck and testrunner in pr/, and cppcheck in base/.
./testrunner -q(all tests): 5387 tests, 0 failures.
<<= / >>= are missed (scratch/sh.cpp):
#include <utility>
#include <vector>
struct S { std::vector<int> v; S& operator+=(int); S& operator<<=(int); S& operator>>=(int); };
void s1(S x) { S a{ std::move(x) }; x += 1; }
void s2(S x) { S a{ std::move(x) }; x <<= 1; }
void s3(S x) { S a{ std::move(x) }; x >>= 1; }cppcheck -q --enable=warning --library=std sh.cpp
- base: nothing
- pr: only
sh.cpp:4:37: warning: Access of moved variable 'x'. [accessMoved]. Nothing is reported for lines 5 and 6.
The same inconsistency shows with uninitialized values: in pr, int x; x += y; gives uninitvar, but int x; x <<= y; still gives only legacyUninitvar.
Other checks:
- The PR's case (
std::stringwith+=after a move) now givesaccessMoved, as intended. x = "abc"; x += "d";andx.clear(); x += "d";after a move: no false positive.void f(int a, int *p = 0) { p += a; }: the newnullPointerArithmeticmatches what base already reports forint *q = p + a;.- Integer
x = 0; x += h(y); if (x == 0)andx |= h(y): no new warnings.
Automated review of 5812614 by Claude. The pull request was built and tested locally.
| if (isVariableChanged(tok, getIndirect(tok), getSettings())) { | ||
| if (Token::Match(tok->astParent(), "*|[|.|++|--")) | ||
| if (Token::Match(tok->astParent(), "*|[|.|++|--") || | ||
| (tok->astParent() && tok->astParent()->isAssignmentOp() && tok->astParent()->str().size() == 2)) // compound assignment |
There was a problem hiding this comment.
AI review
str().size() == 2 misses <<= and >>= (both 3 characters). For a moved S x with S& operator<<=(int), x <<= 1; still gets no accessMoved, while x += 1; now does. With uninitialized ints, x += y now gives uninitvar but x <<= y stays legacyUninitvar. tok->astParent()->str() != "=" would cover all compound assignments.
No description provided.