@@ -1295,17 +1295,28 @@ const Token* CheckUninitVarImpl::isVariableUsage(const Token *vartok, const Libr
12951295 }
12961296 if (alloc != NO_ALLOC && astIsRhs (valueExpr))
12971297 return nullptr ;
1298- } else if (tok->astParent () && tok->astParent ()->isAssignmentOp ()) {
1299- // all variables in a compound assignment get read, so NO_ALLOC is
1300- // never acceptable
1301- if (alloc != NO_ALLOC ) {
1302- // if its not a pointer or array, or not dereferenced it is safe
1303- if (!(pointer || alloc == ARRAY ) || !derefValue) {
1304- return nullptr ;
1305- }
1298+ } else if (tok->astParent () && (tok->astParent ()->isAssignmentOp () || tok->astParent ()->isIncDecOp ())) {
1299+ // NO_ALLOC -> no matter what we read the uninitialized memory.
1300+ // pointer/array -> safe, as long as we don't dereference
1301+ //
1302+ // sometimes "pointer" and "alloc == ARRAY" are used for things
1303+ // that aren't actually pointers or arrays.
1304+ //
1305+ // this test
1306+ // ctu("void increment(int& i) { ++i; }\n" // #6475
1307+ // uses the callback which hardcodes pointer = true and alloc = ARRAY
1308+ // though int& isn't a pointer or an array, and we expect this
1309+ // function to not return nullptr even though i is not dereferenced
1310+ bool isPtr = pointer;
1311+ bool isArr = alloc == ARRAY ;
1312+ if (vartok && vartok->variable ()) {
1313+ isPtr = vartok->variable ()->isPointer ();
1314+ isArr = vartok->variable ()->isArray ();
1315+ }
1316+ if ((alloc != NO_ALLOC ) && ((isPtr || isArr) && !derefValue)) {
1317+ return nullptr ;
13061318 }
13071319 }
1308-
13091320 }
13101321
13111322 // Initialize reference variable
0 commit comments