AI review of 2026-10-18_01-45-32-71c2a236a80c-results.txt PR: #8720 https://github.com/cppcheck-opensource/cppcheck/pull/8720 Tested: 71c2a236a80c0cb9b615ff6871fb2bc48a3506a7 Merge base: 99ad2a83ab14c29d753272388b916887d936af03 Reviewed: 2026-10-19 14:50:06 UTC Model: claude-opus-5-5 (effort high) Results: 50 reviewed of 240 in the report (random sample), 5 not reviewed: valueFlowMaxIterations Verdicts: 20 improvement, 5 neutral, 25 regression Tokens: 126130 input, 3086200 cache read, 771550 cache write, 34976 output The verdicts are written by AI and can be wrong. ---- 1 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/b/btanks/btanks_0.9.8083.orig.tar.bz2 Result: your btanks-0.9.8083/editor/base_brush.h:73:1: debug: SymbolDatabase couldn't resolve all user defined types. [debug] Explanation: The PR adds a new debug message, 'SymbolDatabase couldn't resolve all user defined types', at a plain class declaration (`class Eraser : public Brush`). Its members, such as `v2` and `sdlx::Surface`, resolved fine before. This code itself contains no function template call to deduce. The likely cause is that the new type-deduction rounds rebuild or incrementally update the symbol database, and some user-defined type pointers end up unset. A new debug message on code that was handled before means Cppcheck now understands the code worse. ---- 2 / 50 ---- Verdict: NEUTRAL (medium confidence) Package: https://ftp.debian.org/debian/pool/main/c/coot/coot_1.1.18+dfsg.orig.tar.xz Result: main coot-1.1.18+dfsg/coot-utils/tree.hh:44:3: style: Class 'tree_node_' has a constructor with 1 argument that is not explicit. [noExplicitConstructor] Explanation: Line 44 declares `tree_node_(T&&)`, a one-argument constructor that is not explicit, so the noExplicitConstructor warning is a true positive. The PR only removed the version of the warning that named the uninstantiated template `tree_node_`. The same warning at the same line is still reported, now with the instantiated class names `tree_node_ < linked_residue_t >` and `tree_node_ < coot :: linked_residue_t >`, because the template is now instantiated. No finding is lost. The only difference is the class name in the message, plus a possible duplicate for what may be the same type under two spellings. That does not meaningfully change what users see. ---- 3 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/c/coot/coot_1.1.18+dfsg.orig.tar.xz Result: your coot-1.1.18+dfsg/coot-utils/tree.hh:43:3: style: Class 'tree_node_ < coot :: linked_residue_t >' has a constructor with 1 argument that is not explicit. [noExplicitConstructor] Explanation: The single-argument constructor `tree_node_(const T&)` really is not explicit, so the finding itself is a true positive. Main already reported it once, for the template `tree_node_`. With the PR it is reported twice at the same line, for `tree_node_ < coot :: linked_residue_t >` and `tree_node_ < linked_residue_t >`. These are very likely the same type: the new deduction inserts the namespace-qualified name, while the existing explicit `tree` usage inside namespace coot stays unqualified. So the template simplifier now creates duplicate instantiations of one type. That gives duplicated, noisier warnings here, and new duplicated operatorEqVarError warnings elsewhere in this package. The message is no more useful than main's, and the duplication shows a worse model of the code. ---- 4 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/c/coot/coot_1.1.18+dfsg.orig.tar.xz Result: your coot-1.1.18+dfsg/coot-utils/tree.hh:626:60: warning:inconclusive: Member variable 'tree < coot :: linked_residue_t , std :: allocator < tree_node_ < coot :: linked_residue_t > > >::alloc_' is not assigned a value in 'tree < coot :: linked_residue_t , std :: allocator < tree_node_ < coot :: linked_residue_t > > >::operator='. [operatorEqVarError] Explanation: The PR now instantiates the `tree` template through type deduction. It produced two instantiations for the same type, one named `coot :: linked_residue_t` and one named `linked_residue_t`, so every warning is reported twice. The new operatorEqVarError is also of little value. `alloc_` is the tree's own allocator (a std::allocator), and it owns this object's `head`/`feet` nodes. Leaving it unassigned in `operator=` is intentional and correct. The warning is an inconclusive false positive that appears only because of the new, partly duplicated instantiation. ---- 5 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/d/darkradiant/darkradiant_3.9.0.orig.tar.gz Result: main codereader-DarkRadiant-f84caab/libs/pugixml/pugixml.cpp:10443:27: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable axis [valueFlowBailoutIncompleteVar] Explanation: Line 10443 is inside the member function template `step_do`. pugixml calls it with temporaries such as `axis_to_type()`, which are not literals. Main could not deduce T from these calls, so it analyzed the uninstantiated template body. There `T::axis` leaves `axis` as an incomplete variable, which triggered the valueFlow bailout. With the PR, T is deduced from the argument's record type, `step_do` is instantiated, and the generic template body is removed. The debug bailout therefore disappears because Cppcheck now sees concrete instantiations. The other new findings in pugixml in this package also point to more template code being instantiated and checked. This is a debug message vanishing for a good reason. ---- 6 / 50 ---- Verdict: IMPROVEMENT (low confidence) Package: https://ftp.debian.org/debian/pool/main/d/darkradiant/darkradiant_3.9.0.orig.tar.gz Result: your codereader-DarkRadiant-f84caab/radiantcore/model/import/openfbx/ofbx.cpp:2056:33: portability:inconclusive: Casting from double * to unsigned char * is not portable due to different binary data representations on different platforms. [invalidPointerCast] Explanation: The PR's new type deduction now instantiates `parseArrayRaw` (and ``) from calls such as `parseArrayRaw(prop, double_ptr, ...)`, where `T*` is correctly deduced as `double`. Inside that instantiation, `(u8*)out` casts `double*` to `unsigned char*`. Cppcheck reports such casts to char types by design, but only as inconclusive portability warnings, and it does the same for equivalent non-template code. The concern is real here: raw decompressed file bytes are written straight into a `double` array, which assumes a particular binary layout and endianness. The warning comes from correct new analysis of template code that Cppcheck could not see before, so it is a consistent, if low-value, inconclusive finding rather than a false positive. ---- 7 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/d/darkradiant/darkradiant_3.9.0.orig.tar.gz Result: your codereader-DarkRadiant-f84caab/radiantcore/model/import/openfbx/ofbx.cpp:2056:33: portability:inconclusive: Casting from float * to unsigned char * is not portable due to different binary data representations on different platforms. [invalidPointerCast] Explanation: The PR now deduces `T=float` for calls such as `parseArrayRaw(property, float_ptr, ...)` and instantiates the template body. In that body `(u8*)out` casts the output buffer to `unsigned char*` so `decompress()` can write raw bytes into it, just as the `memcpy` a few lines above does. Accessing any object through `unsigned char*` is well defined; this is the standard idiom for byte-wise filling of a buffer. Cppcheck itself only reports char-target casts as inconclusive. The new warning (`float*` to `unsigned char*`) is therefore a likely false positive and noise for users. The deduction itself is correct, but the warning it exposes is not useful. ---- 8 / 50 ---- Verdict: IMPROVEMENT (low confidence) Package: https://ftp.debian.org/debian/pool/main/d/delly/delly_1.7.2.orig.tar.xz Result: your delly-1.7.2/src/asmode.h:341:18: style: Parameter 'c' can be declared as reference to const [constParameterReference] Explanation: `runAsm(TConfig& c)` is a function template called with a variable argument (e.g. `runAsm(c)` with an `AsmConfig`). Main could not deduce `TConfig` from a non-literal argument, so the body was never instantiated or checked. With the PR's type deduction, `runAsm` is instantiated and its body is analysed. In the visible code, `c` is only read (`c.files.size()`) or passed to helpers. In delly these helpers (`_findAsmStructuralVariants`, `_setAsmConsensus`, output functions) take `TConfig const&`. So `c` can plausibly be `const&`, and this looks like a newly found true positive. The full body is not shown, so a write to `c` further down cannot be ruled out. ---- 9 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/d/devil/devil_1.8.0.40.g6f3d5e9b+dfsg.orig.tar.xz Result: main devil-v1.8.0.40.g6f3d5e9b/DevIL/src-IL/src/rg_etc1.cpp:748:58: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable T [valueFlowBailoutIncompleteVar] Explanation: Line 748 is in the uninstantiated function template `indirect_radix_sort`. In the generic body, `sizeof(T)` refers to an unknown `T`, so ValueFlow skipped the whole function as containing an incomplete variable. The PR adds type deduction for calls with non-literal arguments. Calls such as `indirect_radix_sort(n, &indices[0], ..., &keys[0], ...)` can now be instantiated with concrete types and the generic template removed. With `T` replaced by a real type, the bailout goes away and the function body actually gets analyzed. That is better understanding of the code, not lost coverage. The source does not show the call site, so the exact cause cannot be confirmed. ---- 10 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/d/dxvk/dxvk_3.1.1+ds.orig.tar.xz Result: main dxvk-3.1.1/src/util/util_string.cpp:26:14: style: Local variable 'length' shadows outer function [shadowFunction] dxvk-3.1.1/src/util/util_string.h:110:10: note: Shadowed function dxvk-3.1.1/src/util/util_string.cpp:26:14: note: Shadow local variable Explanation: At line 26 the local variable `length` really does shadow the function `dxvk::str::length` declared at util_string.h:110, so main's shadowFunction warning is a true positive. That function is most likely a function template. The PR now deduces its template arguments from non-literal call arguments, instantiates it as `length<...>` and removes the original `length` declaration. The shadow check then no longer finds a function named `length`. The code did not change; Cppcheck only lost the warning because of how the instantiation renames the function, so a valid style finding disappeared. ---- 11 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/d/dxvk/dxvk_3.1.1+ds.orig.tar.xz Result: your dxvk-3.1.1/subprojects/dxbc-spirv/ir/passes/ir_pass_arithmetic.cpp:4984:22: style: The member function 'dxbc_spv::ir::ArithmeticPass::isConstantValue < int >' can be static. [functionStatic] dxvk-3.1.1/subprojects/dxbc-spirv/ir/passes/ir_pass_arithmetic.h:261:8: note: The member function 'dxbc_spv::ir::ArithmeticPass::isConstantValue < int >' can be static. dxvk-3.1.1/subprojects/dxbc-spirv/ir/passes/ir_pass_arithmetic.cpp:4984:22: note: The member function 'dxbc_spv::ir::ArithmeticPass::isConstantValue < int >' can be static. Explanation: `isConstantValue` is a member function template whose body uses only `op` and the free function `makeScalarOperand`, so the functionStatic finding is a true positive. Main reported it once, for the template itself. With the PR, the new type deduction instantiates the template per deduced type (double, int, long, unsigned int), and the same warning now appears four times at the same location, each naming an instantiation such as `isConstantValue < int >`. The `` instantiation is plausible (e.g. a call with a literal `0`), so the line is not wrong. But it duplicates the original finding and names an instantiation, while the fix belongs on the template. The output is noisier and less precise, not more informative. ---- 12 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/f/fastml/fastml_3.11.orig.tar.gz Result: your FastML.v3.11/libs/phylogeny/likeDist.cpp:182:69: performance: Function parameter 'f' should be passed by const reference. [passedByValue] Explanation: The new warning comes from the PR's type deduction. `myNRmethod` is a function template, and `f` has the template type `regF`. Deducing `regF` from a call site instantiates the template with a concrete functor type, and passedByValue then fires on that instantiation. Passing callable objects by value in generic code is the idiomatic C++ convention (as in the STL). The template author cannot pick a parameter type per instantiation. Also, FastML's evaluator functors (e.g. `C_evalLikeDist`) likely have non-const `operator()`, so taking `f` as a const reference would probably not compile. The warning is noise produced by the new instantiation, not a real performance issue in this code. ---- 13 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/f/ffc/ffc_2019.2.0~legacy20230509.35df986.orig.tar.bz2 Result: main fenics-project-ffc-35df9863d278/libs/gtest-1.7.0/src/gtest-printers.cc:257:42: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable CharType [valueFlowBailoutIncompleteVar] Explanation: `PrintCharsAsStringTo` is a function template. It is called only without explicit template arguments: `PrintCharsAsStringTo(begin, len, os)` with `begin` being `const char*` or `const wchar_t*`, reached via `UniversalPrintCharArray`. Before the PR, cppcheck could only deduce template arguments from literal arguments. So the template stayed uninstantiated, `CharType` was an unknown name, and ValueFlow gave up on the function with this bailout. The PR deduces template arguments from the types of argument expressions: `const char*` against a `const T*` parameter gives `T = char`. The function is then instantiated with a concrete type and the generic template is removed, so the incomplete-variable bailout goes away because cppcheck now analyzes real instantiations. Losing this debug message reflects better understanding of the code. ---- 14 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/g/godot3/godot3_3.6.2+ds.orig.tar.xz Result: main godotengine-godot-3cd3caa/thirdparty/oidn/core/api.cpp:84:11: warning: Either the condition 'obj==nullptr' is redundant or there is possible null pointer dereference: obj. [nullPointerRedundantCheck] godotengine-godot-3cd3caa/thirdparty/oidn/core/api.cpp:80:15: note: Assuming that condition 'obj==nullptr' is not redundant godotengine-godot-3cd3caa/thirdparty/oidn/core/api.cpp:84:11: note: Null pointer dereference Explanation: In `releaseObject`, the null case of `obj == nullptr` first calls `checkHandle(obj)`. That function throws when the handle is null, so `OIDN_LOCK(obj)` and `obj->destroy()` are never reached with a null `obj`. The nullPointerRedundantCheck warning is therefore a false positive. With the PR, calls like `releaseObject(filter)` are deduced and instantiated with concrete types, so Cppcheck analyses the code differently and the false positive goes away. ---- 15 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/g/godot3/godot3_3.6.2+ds.orig.tar.xz Result: main godotengine-godot-3cd3caa/thirdparty/oidn/core/api.cpp:85:11: warning: Either the condition 'obj==nullptr' is redundant or there is possible null pointer dereference: obj. [nullPointerRedundantCheck] godotengine-godot-3cd3caa/thirdparty/oidn/core/api.cpp:80:15: note: Assuming that condition 'obj==nullptr' is not redundant godotengine-godot-3cd3caa/thirdparty/oidn/core/api.cpp:85:11: note: Null pointer dereference Explanation: In `releaseObject`, `checkHandle(obj)` throws when `obj` is null, so `obj->destroy()` at line 85 is never reached with a null `obj`. The warning was a false positive. Main does not report the same pattern in the explicit `releaseObject(Device*)` specialization (line 98), so Cppcheck already handles the throwing `checkHandle` in ordinary code. The difference came from analyzing the uninstantiated template. With the PR, calls like `releaseObject(filter)` now get their template argument deduced, the template is instantiated, and the false positive disappears. ---- 16 / 50 ---- Verdict: REGRESSION (low confidence) Package: https://ftp.debian.org/debian/pool/main/i/injeqt/injeqt_1.2.0.orig.tar.gz Result: main injeqt-1.2.0/src/internal/injector-core.cpp:200:14: style: Variable 'provider' can be declared as pointer to const [constVariableReference] Explanation: Line 200 loops over `providers_for(...)`, which most likely returns pointers to `provider`. The loop body only calls `provider->required_types()`, which in injeqt is very likely a const member function. So the pointee is never modified and suggesting `const auto*` is a legitimate style finding. Nothing in this loop deduces a template argument, so the PR's template deduction work does not make Cppcheck understand this code better. The disappearance looks like a side effect of the reordered or incremental symbol database phases, which means a probable true positive was lost. Confidence is low because the provider declarations are not shown. ---- 17 / 50 ---- Verdict: REGRESSION (high confidence) Package: https://ftp.debian.org/debian/pool/main/i/inspircd/inspircd_4.7.0+ds1.orig.tar.gz Result: your inspircd-4.7.0+ds1/src/coremods/core_who.cpp:232:63: style: Parameter 't' can be declared as reference to const [constParameterReference] Explanation: Line 232 is an explicit specialization of the member template `template static User* GetUser(T& t)`. Its parameter type is fixed by the primary template's `T&`. Writing `const UserMap::const_iterator&` would not change this specialization. It would declare a specialization for a different T (`const UserMap::const_iterator`), so calls with a non-const iterator would no longer use it. The constParameterReference suggestion therefore cannot be applied, and the new warning is a false positive. It is most likely caused by the PR's type deduction and template rewriting turning the specialization into a plain function, so the check stops recognizing it as template code. ---- 18 / 50 ---- Verdict: REGRESSION (high confidence) Package: https://ftp.debian.org/debian/pool/main/i/intel-graphics-compiler2/intel-graphics-compiler2_2.40.14.orig.tar.gz Result: your intel-intel-graphics-compiler-3c890d7/visa/iga/IGALibrary/Frontend/Parser.hpp:234:30: style: The member function 'iga::Parser::ParseIntFrom < int >' can be static. [functionStatic] intel-intel-graphics-compiler-3c890d7/visa/iga/IGALibrary/Frontend/Parser.hpp:234:30: note: The member function 'iga::Parser::ParseIntFrom < int >' can be static. intel-intel-graphics-compiler-3c890d7/visa/iga/IGALibrary/Frontend/Parser.hpp:234:30: note: The member function 'iga::Parser::ParseIntFrom < int >' can be static. Explanation: `ParseIntFrom(const Loc&, T&)` forwards to the 3-argument `ParseIntFrom(off, len, value)` overload. That overload uses the member `m_lexer` and calls `FailS`, so the 2-argument function needs `this` and cannot be static. The PR now deduces and instantiates `ParseIntFrom` and similar from type information. However, the call inside the instantiated body is not linked to the member overload, so the check thinks the function uses no members. The new functionStatic warning is a false positive. ---- 19 / 50 ---- Verdict: REGRESSION (high confidence) Package: https://ftp.debian.org/debian/pool/main/i/intel-graphics-compiler2/intel-graphics-compiler2_2.40.14.orig.tar.gz Result: your intel-intel-graphics-compiler-3c890d7/visa/iga/IGALibrary/Frontend/Parser.hpp:234:30: style: The member function 'iga::Parser::ParseIntFrom < unsigned int >' can be static. [functionStatic] intel-intel-graphics-compiler-3c890d7/visa/iga/IGALibrary/Frontend/Parser.hpp:234:30: note: The member function 'iga::Parser::ParseIntFrom < unsigned int >' can be static. intel-intel-graphics-compiler-3c890d7/visa/iga/IGALibrary/Frontend/Parser.hpp:234:30: note: The member function 'iga::Parser::ParseIntFrom < unsigned int >' can be static. Explanation: The 2-argument `ParseIntFrom(const Loc&, T&)` forwards to the 3-argument member template `ParseIntFrom(off, len, value)`. That overload is non-static: it reads `m_lexer.GetSource()` and calls the member `FailS`. So the forwarding instantiation `ParseIntFrom` cannot be static. The new type deduction now instantiates these member templates from calls with non-literal arguments. Cppcheck then evidently fails to treat the inner call as a call to a non-static member, which produces this new false positive. ---- 20 / 50 ---- Verdict: REGRESSION (high confidence) Package: https://ftp.debian.org/debian/pool/main/i/intel-graphics-compiler2/intel-graphics-compiler2_2.40.14.orig.tar.gz Result: your intel-intel-graphics-compiler-3c890d7/visa/iga/IGALibrary/Frontend/Parser.hpp:234:30: style: The member function 'iga::Parser::ParseIntFrom < unsigned short >' can be static. [functionStatic] intel-intel-graphics-compiler-3c890d7/visa/iga/IGALibrary/Frontend/Parser.hpp:234:30: note: The member function 'iga::Parser::ParseIntFrom < unsigned short >' can be static. intel-intel-graphics-compiler-3c890d7/visa/iga/IGALibrary/Frontend/Parser.hpp:234:30: note: The member function 'iga::Parser::ParseIntFrom < unsigned short >' can be static. Explanation: `ParseIntFrom(const Loc&, T&)` forwards to the 3-argument overload `ParseIntFrom(off, len, value)`. That overload is a non-static member template: it uses `m_lexer` and calls `FailS`. So the wrapper cannot be static. With the PR's new type deduction, the 1-argument overload is now instantiated as `ParseIntFrom`. Cppcheck likely no longer links the inner call to the member overload, plausibly because both overloads get the same instantiated name. As a result it wrongly concludes the function does not use `this`. The new functionStatic warning is a false positive. ---- 21 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/k/kodi-peripheral-joystick/kodi-peripheral-joystick_21.1.23+ds.orig.tar.xz Result: your kodi-peripheral-joystick-21.1.23/src/buttonmapper/ButtonMapTypes.h:55:3: debug: SymbolDatabase couldn't resolve all user defined types. [debug] Explanation: The PR adds a new debug message, "SymbolDatabase couldn't resolve all user defined types", at `struct FeaturePrimitive`. The source of this struct is unchanged and main did not report it. The PR's new template type-deduction rounds rebuild the symbol database or update it incrementally. Those paths apparently leave the member types (`kodi::addon::JoystickFeature`, `JOYSTICK_FEATURE_PRIMITIVE`) handled worse than the original single build. A new debug message of this kind means Cppcheck understands the code worse, not better. ---- 22 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/l/lincity-ng/lincity-ng_2.15.0.orig.tar.gz Result: your lincity-ng-lincity-ng-2.15.0/src/lincity/xmlloadsave.cpp:979:21: style: Variable 'cst' can be declared as pointer to const [constVariablePointer] Explanation: In `saveMap()`, `cst` is only used for reads: `isDead()`, `constructionGroup->group`, `point.x`/`point.y`, and `save(xmlWriter)`, which is presumably const in lincity-ng's Construction API (not shown). The pointee is never modified, so `const Construction *cst` would work and the warning looks like a true positive. Before the PR, the `f(cst->point.x)` calls (presumably a function template, definition not shown) could not be instantiated because they have non-literal arguments. Cppcheck therefore had to assume they might modify the pointee. With the new type deduction, `f` is instantiated with a concrete parameter type and that assumption goes away. Confidence is medium because neither the `save()` signature nor the definition of `f` is visible here. ---- 23 / 50 ---- Verdict: IMPROVEMENT (low confidence) Package: https://ftp.debian.org/debian/pool/main/libg/libgdiplus/libgdiplus_6.1+dfsg.orig.tar.xz Result: main libgdiplus-6.1+dfsg/external/googletest/googletest/test/googletest-printers-test.cc:942:8: style: struct member 'iterator::x' is never used. [unusedStructMember] Explanation: `struct iterator { char x; };` exists only to give the object a defined 1-byte content. The test zero-initialises it with `{}` and calls `Print(it)`, which prints the object's raw bytes ("1-byte object <00>"). So `x` is never named, but its value is observed through the byte-wise printing. With the PR, the call `Print(it)` is deduced as `Print` and instantiated, so Cppcheck now sees the struct value passed into real code. That is probably why the unusedStructMember warning (and the matching `const_iterator::x` one) went away. Removing the member would change what the test observes, so the warning is noise for users here. Dropping it looks like a small improvement, although strictly the member is never accessed by name. ---- 24 / 50 ---- Verdict: REGRESSION (low confidence) Package: https://ftp.debian.org/debian/pool/main/libg/libgdiplus/libgdiplus_6.1+dfsg.orig.tar.xz Result: main libgdiplus-6.1+dfsg/external/googletest/googletest/test/googletest-printers-test.cc:953:8: style: struct member 'const_iterator::x' is never used. [unusedStructMember] Explanation: `struct const_iterator { char x; };` is only zero-initialized (`= {}`) and passed whole to `Print(it)`. Nothing ever reads `x` by name, so by the check's definition the unusedStructMember warning is a true positive. The PR now deduces `Print(it)` as `Print` from the variable's type and instantiates it. That probably makes the unusedStructMember check bail out for this struct, although the code that `Print` instantiates does not access `x` either. The warning disappears as a side effect, not because `x` is used. The same happens for the sibling `iterator::x` warning. One caveat lowers confidence: the member arguably exists to give the struct a defined 1-byte layout for the printed output, so the warning has little value here. ---- 25 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/libv/libvigraimpex/libvigraimpex_1.12.4+dfsg.orig.tar.xz Result: main vigra-Version-1-12-4/test/filter_iterator/test.cxx:61:10: style: The member function 'FilterIteratorTests::test_filter_write_mod2' can be static. [functionStatic] Explanation: The template member test_filter_write_mod2 does not use `this`, so the old functionStatic warning on line 61 was a true positive naming the real source function. With the PR, the call with int* arguments is deduced and instantiated. The same warning is now reported as 'test_filter_write_mod2 < int * , int * >', and it carries duplicated notes. That name does not exist in the source, and the fix (making the template static) applies to the template as a whole, not to one instantiation. The finding is kept but the message is less accurate. ---- 26 / 50 ---- Verdict: NEUTRAL (medium confidence) Package: https://ftp.debian.org/debian/pool/main/libv/libvigraimpex/libvigraimpex_1.12.4+dfsg.orig.tar.xz Result: your vigra-Version-1-12-4/test/filter_iterator/test.cxx:46:10: style: The member function 'FilterIteratorTests::test_filter_read_mod2 < int * , int * >' can be static. [functionStatic] vigra-Version-1-12-4/test/filter_iterator/test.cxx:46:10: note: The member function 'FilterIteratorTests::test_filter_read_mod2 < int * , int * >' can be static. vigra-Version-1-12-4/test/filter_iterator/test.cxx:46:10: note: The member function 'FilterIteratorTests::test_filter_read_mod2 < int * , int * >' can be static. Explanation: `test_filter_read_mod2` uses no members, so the functionStatic warning is a true positive both before and after the PR. The PR now deduces `` from the array arguments in `test_filter_read_mod2(in, in+10, out_expected)` and checks the instantiated function instead of the template. As a result, the message names the instantiation `test_filter_read_mod2 < int * , int * >` rather than the template, and it carries two redundant notes at the same location. The location, the finding and the fix (make the template static) are unchanged. The wording is only cosmetically different and slightly noisier, so it does not matter to users either way. ---- 27 / 50 ---- Verdict: NEUTRAL (medium confidence) Package: https://ftp.debian.org/debian/pool/main/libv/libvigraimpex/libvigraimpex_1.12.4+dfsg.orig.tar.xz Result: your vigra-Version-1-12-4/test/filter_iterator/test.cxx:61:10: style: The member function 'FilterIteratorTests::test_filter_write_mod2 < int * , int * >' can be static. [functionStatic] vigra-Version-1-12-4/test/filter_iterator/test.cxx:61:10: note: The member function 'FilterIteratorTests::test_filter_write_mod2 < int * , int * >' can be static. vigra-Version-1-12-4/test/filter_iterator/test.cxx:61:10: note: The member function 'FilterIteratorTests::test_filter_write_mod2 < int * , int * >' can be static. Explanation: Both versions report the same true positive at the same line. test_filter_write_mod2 uses no members of FilterIteratorTests, so it can be static. The only change is the name in the message. Main checked the uninstantiated template and printed the plain name. The PR now deduces the template arguments from the `int[]` arguments, instantiates `test_filter_write_mod2`, and reports that instantiation by name. The advice is still correct and points at the same declaration. The added `< int * , int * >` is slightly noisier, since the fix applies to the whole template, but this is how Cppcheck already names explicitly instantiated templates. It makes no practical difference to users. ---- 28 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/o/oclgrind/oclgrind_21.10.orig.tar.gz Result: your Oclgrind-21.10/src/core/WorkItemBuiltins.cpp:461:59: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable _max_ [valueFlowBailoutIncompleteVar] Explanation: `_max_` is used both as a direct call (`_max_(x, y)` with doubles, line 453) and as a function name passed to `u2arg`/`s2arg` (lines 461/467). It is very likely a function template. With the PR, the direct call is deduced as `_max_` and instantiated. The original template declaration is then removed, so the bare `_max_` passed as a function pointer at line 461 no longer refers to anything. Cppcheck now treats it as an incomplete variable and skips the whole function in valueFlowConditionExpressions. This new bailout means Cppcheck understands this code worse than before; the code itself did not change. ---- 29 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/o/openscenegraph/openscenegraph_3.6.5+dfsg1.orig.tar.gz Result: main OpenSceneGraph-OpenSceneGraph-3.6.5/src/osgDB/ClassInterface.cpp:110:69: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable T [valueFlowBailoutIncompleteVar] Explanation: The removed line is a debug bailout: ValueFlow skipped the uninstantiated template `read(T& value)` because `T` was an incomplete variable. With the PR, calls like `read(c)` and `read(f)` are deduced from the argument types and instantiated (e.g. `read`, `read`). So the bailout no longer happens because Cppcheck now understands the code better. The invalidPointerCast warnings added at the same line come from those instantiations; they are a separate result. ---- 30 / 50 ---- Verdict: IMPROVEMENT (high confidence) Package: https://ftp.debian.org/debian/pool/main/o/openscenegraph/openscenegraph_3.6.5+dfsg1.orig.tar.gz Result: main OpenSceneGraph-OpenSceneGraph-3.6.5/src/osgDB/ClassInterface.cpp:47:46: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable T [valueFlowBailoutIncompleteVar] Explanation: `write(T t)` is a member function template. It is called with variables such as `write(s)` and `write(f)`, never with literals, so main could not instantiate it. The uninstantiated body was then analysed with an unknown `T`, which produced the `valueFlowBailoutIncompleteVar` debug message at line 47. The PR deduces template arguments from the argument types, so `write` is now instantiated for each concrete type. Cppcheck therefore understands the code better, and this bailout message disappearing is an improvement. ---- 31 / 50 ---- Verdict: IMPROVEMENT (low confidence) Package: https://ftp.debian.org/debian/pool/main/o/openscenegraph/openscenegraph_3.6.5+dfsg1.orig.tar.gz Result: your OpenSceneGraph-OpenSceneGraph-3.6.5/src/osgDB/ClassInterface.cpp:46:21: portability:inconclusive: Casting from double * to char * is not portable due to different binary data representations on different platforms. [invalidPointerCast] Explanation: `writeDouble(double d)` calls `write(d)`. The PR now correctly deduces `T=double` from the variable's type and instantiates `write`. The body therefore really contains `reinterpret_cast(&t)` with `t` being a double. The invalidPointerCast check then reports what it would report for the same non-template code, and only as inconclusive, which is how it treats char* targets. The matching valueFlowBailoutIncompleteVar debug message for the uninstantiated template disappeared, so Cppcheck understands the code better. The warning is of limited value here: casting to char* for raw byte access is legal, and the bytes are written into a string within the same process. Still, the message is accurate about the platform-dependent byte representation and comes from a correct instantiation, so this leans toward an improvement. ---- 32 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/o/opentimelineio/opentimelineio_0.18.1.orig.tar.gz Result: main opentimelineio-0.18.1/src/deps/rapidjson/thirdparty/gtest/googletest/src/gtest-printers.cc:268:42: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable CharType [valueFlowBailoutIncompleteVar] Explanation: PrintCharsAsStringTo is a function template. The only calls to it pass non-literal arguments, e.g. PrintCharsAsStringTo(begin, len - 1, os) from UniversalPrintCharArray. Before this PR, deduction only worked for literal arguments, so the uninstantiated template body stayed in the token list. CharType was then an incomplete variable and ValueFlow skipped the function, which produced the bailout. The PR deduces template arguments from argument types: `const CharType*` matches the 'const T *' parameter shape. The template is now instantiated (e.g. with char/wchar_t) and the generic body is removed, so the debug bailout disappears because Cppcheck understands the code better. ---- 33 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/p/p7zip/p7zip_16.02+really26.01+dfsg.orig.tar.xz Result: main ip7z-7zip-8c63d71/CPP/Windows/PropVariant.cpp:362:19: style:inconclusive: Technically the member function 'NWindows::NCOM::CPropVariant::Compare' can be const. [functionConst] ip7z-7zip-8c63d71/CPP/Windows/PropVariant.h:168:7: note: Technically the member function 'NWindows::NCOM::CPropVariant::Compare' can be const. ip7z-7zip-8c63d71/CPP/Windows/PropVariant.cpp:362:19: note: Technically the member function 'NWindows::NCOM::CPropVariant::Compare' can be const. Explanation: CPropVariant::Compare only reads members. It compares them via MyCompare by value and calls CompareFileTime(&filetime, &a.filetime). Since `a` is const, CompareFileTime must take const pointers. It also calls Get_Ns100(), which must already be const because it is called on `a`. So the function really can be const, and the functionConst warning was a true positive. It most likely disappeared because the PR's new type deduction now instantiates the MyCompare template calls (e.g. MyCompare(vt, a.vt)). That changes how the call is seen by the const check. A correct warning was lost. ---- 34 / 50 ---- Verdict: REGRESSION (high confidence) Package: https://ftp.debian.org/debian/pool/main/s/s3fs-fuse/s3fs-fuse_1.97.orig.tar.gz Result: your s3fs-fuse-1.97/src/test_util.h:42:14: error: Null pointer dereference: y [ctunullpointer] s3fs-fuse-1.97/src/test_page_list.cpp:35:3: note: Calling function assert_equals < bool >, 2nd argument is null s3fs-fuse-1.97/src/test_util.h:42:14: note: Dereferencing argument y that is null Explanation: The PR now deduces template arguments from variables and expressions, so the call at test_page_list.cpp:35 becomes `assert_equals(..., false, ...)`. The parameters are `const T&` references, so the literal `false` is bound to a reference and is never a null pointer. Cppcheck treats the 0-valued argument as a null pointer passed to a reference parameter. The reported location, line 42, is even in the `std::string` specialization, not in the `bool` instantiation, so the warning is attributed to the wrong function. This is a new false positive. ---- 35 / 50 ---- Verdict: REGRESSION (high confidence) Package: https://ftp.debian.org/debian/pool/main/s/s3fs-fuse/s3fs-fuse_1.97.orig.tar.gz Result: your s3fs-fuse-1.97/src/test_util.h:42:9: error: Null pointer dereference: x [ctunullpointer] s3fs-fuse-1.97/src/test_curl_util.cpp:113:5: note: Calling function assert_equals < unsigned long >, 1st argument is null s3fs-fuse-1.97/src/test_util.h:42:9: note: Dereferencing argument x that is null Explanation: `assert_equals` takes `const T&` parameters. The call at test_curl_util.cpp:113 passes an `unsigned long` value, probably 0. Passing an integer value of 0 by const reference is not a null pointer, and comparing references cannot dereference null. The reported location, line 42, is inside the explicit `std::string` specialization, yet the note says it is the `assert_equals` instantiation. The new type deduction appears to have mixed up the specialization and the generic template, or to have treated a zero value as a null pointer. This new ctunullpointer error is a false positive. ---- 36 / 50 ---- Verdict: IMPROVEMENT (high confidence) Package: https://ftp.debian.org/debian/pool/main/s/shasta/shasta_0.14.0.orig.tar.gz Result: main paoloshasta-shasta-6c634aa/src/MemoryMappedVector.hpp:290:21: debug: CheckClass::isMemberVar found used member variable 'header' with varid 0 [varid0] Explanation: Line 290 is the out-of-line definition of `Vector::size()`, which uses the member `header`. In main, the instantiated body was not recognized as a member function body, so the member got varid 0 and a varid0 debug message was printed. The PR stops adding the namespace/class qualification twice when expanding out-of-line definitions (addNamespace change). The member variables now get variable ids, so the debug message is gone. The removed uninitMemberVar warnings and isOpen bailouts in the same diff fit this explanation. ---- 37 / 50 ---- Verdict: REGRESSION (high confidence) Package: https://ftp.debian.org/debian/pool/main/s/shasta/shasta_0.14.0.orig.tar.gz Result: your paoloshasta-shasta-6c634aa/src/MemoryMappedObject.hpp:368:43: error: If memory allocation fails: pointer addition with NULL pointer. [nullPointerArithmeticOutOfMemory] paoloshasta-shasta-6c634aa/src/MemoryMappedObject.hpp:358:31: note: Assuming allocation function fails paoloshasta-shasta-6c634aa/src/MemoryMappedObject.hpp:358:31: note: Assignment 'pointer=::mmap(0,fileSize,PROT_READ|PROT_WRITE,flags,-1,0)', assigned value is 0 paoloshasta-shasta-6c634aa/src/MemoryMappedObject.hpp:367:38: note: Assignment 'header=static_cast(pointer)', assigned value is 0 paoloshasta-shasta-6c634aa/src/MemoryMappedObject.hpp:368:43: note: Null pointer addition Explanation: The PR now resolves the members of the template class instantiation, and that understanding is better: the varid0 and incomplete-variable bailouts are gone. But it also exposes a new false positive. On failure, `mmap` returns `MAP_FAILED` (`(void*)-1`), not NULL. The code already checks for that value at line 361 and throws. With a null hint and no `MAP_FIXED`, `mmap` does not return 0 on success either. So `pointer`, and therefore `header`, cannot be NULL at line 368. The 'pointer addition with NULL pointer' error is wrong, so a new false positive was added. ---- 38 / 50 ---- Verdict: NEUTRAL (medium confidence) Package: https://ftp.debian.org/debian/pool/main/s/simgear/simgear_2024.1.5+dfsg.orig.tar.xz Result: main simgear-2024.1.5/simgear/math/SGBox.hxx:28:3: style: Class 'SGBox' has a constructor with 1 argument that is not explicit. [noExplicitConstructor] Explanation: Line 28 declares `SGBox(const SGVec3& pt)`, a one-argument constructor that is not `explicit`, so the noExplicitConstructor warning is a true positive. In main it was reported once on the uninstantiated template 'SGBox'. With the PR, type deduction now instantiates SGBox and SGBox, so the same finding is reported once per instantiation, at the same location. The true positive is kept, not lost. The only differences are the class name in the message and one extra duplicate line, which matter little to users. ---- 39 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/s/simgear/simgear_2024.1.5+dfsg.orig.tar.xz Result: main simgear-2024.1.5/simgear/math/SGGeometryTest.cxx:332:14: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable T [valueFlowBailoutIncompleteVar] Explanation: Removed debug bailout at line 332. The function template SphereLineIntersectionTest uses 'T' as a type. The main run was analyzing an uninstantiated template body, so 'T' looked like an incomplete variable. With the PR, type deduction instantiates more templates (e.g. SGBox/SGBox now appear in other diff lines). The template body is now handled as concrete instantiations. The same function now gets a bailout at line 348 about 'cout', which is the normal std::cout unknown-library bailout. Cppcheck therefore understands the code better: the bailout on the template parameter T is gone. ---- 40 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/s/simgear/simgear_2024.1.5+dfsg.orig.tar.xz Result: main simgear-2024.1.5/simgear/math/SGLineSegment.hxx:53:19: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable T [valueFlowBailoutIncompleteVar] Explanation: The removed bailout came from an uninstantiated template, where 'T' was an incomplete variable. The PR deduces template arguments from typed call arguments (e.g. in SGGeometryTest), so SGLineSegment and the related templates are now instantiated with concrete types. The bailout on the generic T body disappears because Cppcheck now analyzes concrete instantiations. The neighbouring diff lines show the same pattern (SGBox/SGBox, SGTriangle/SGTriangle). Losing a debug bailout caused by an uninstantiated template is an improvement. ---- 41 / 50 ---- Verdict: IMPROVEMENT (high confidence) Package: https://ftp.debian.org/debian/pool/main/s/simgear/simgear_2024.1.5+dfsg.orig.tar.xz Result: main simgear-2024.1.5/simgear/misc/strutils_test.cxx:141:12: style: Unsigned expression 'nbValues' can't be negative so it is unnecessary to test it. [unsignedPositive] Explanation: `nbValues` has type `T`, a template parameter of `aux_readNonNegativeInt_testValuesCloseToMax`. The `0 <= nbValues` check in the assert is generic code: it is pointless only for the unsigned instantiations and meaningful for signed `T`. Reporting 'unsigned expression can't be negative' on template-dependent code is a false positive. The PR changes `testIfNonZeroExpressionIsPositive` to skip variables whose type token is a template argument, which removes exactly this warning. ---- 42 / 50 ---- Verdict: IMPROVEMENT (high confidence) Package: https://ftp.debian.org/debian/pool/main/s/simgear/simgear_2024.1.5+dfsg.orig.tar.xz Result: main simgear-2024.1.5/simgear/sound/readwav.cxx:241:35: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable T [valueFlowBailoutIncompleteVar] Explanation: wavReadBE is a function template that is called only with variables as arguments, e.g. wavReadBE(fd, magic) where magic is int32_t. Main could not deduce T from such calls, so the template stayed uninstantiated. ValueFlow then bailed out on the raw template body because 'T' looked like an incomplete variable. With the PR, T is deduced from the argument's type (int32_t&) and the template is instantiated. The bailout disappears because Cppcheck now understands the code better. ---- 43 / 50 ---- Verdict: IMPROVEMENT (high confidence) Package: https://ftp.debian.org/debian/pool/main/s/simgear/simgear_2024.1.5+dfsg.orig.tar.xz Result: main simgear-2024.1.5/simgear/sound/readwav.cxx:253:35: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable T [valueFlowBailoutIncompleteVar] Explanation: wavReadLE is a function template that is only called with variable arguments, e.g. wavReadLE(fd, chunkLength). In main, Cppcheck could not deduce the template argument from a variable, so the uninstantiated template body was analysed and ValueFlow bailed out on the unknown 'T'. The PR deduces T from the argument's ValueType (uint32_t, uint16_t, ...) and instantiates the template. The debug bailout disappears because Cppcheck now understands the code better. ---- 44 / 50 ---- Verdict: NEUTRAL (medium confidence) Package: https://ftp.debian.org/debian/pool/main/s/simgear/simgear_2024.1.5+dfsg.orig.tar.xz Result: your simgear-2024.1.5/simgear/math/SGGeometryTest.cxx:348:14: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable cout [valueFlowBailoutIncompleteVar] Explanation: This line is half of a pair: main reported a valueFlowConditionExpressions bailout at 332:14 for 'incomplete variable T', and the PR reports one at 348:14 for 'incomplete variable cout'. Both are in SphereLineIntersectionTest. With the PR, the template's type arguments are now deduced (the call sites are partly visible in the diff), so the T bailout goes away. The function is still skipped, though, because std::cout is unknown: the standard headers are not analyzed. Only the reason for the same bailout changed. The new reason is a real unresolved external symbol rather than a template parameter, but valueflow coverage for users is the same, so the change is effectively neutral. ---- 45 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/s/simgear/simgear_2024.1.5+dfsg.orig.tar.xz Result: your simgear-2024.1.5/simgear/math/SGQuat.hxx:482:22: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable d0 [valueFlowBailoutIncompleteVar] Explanation: `d0` is a local variable declared at line 478 (`SGQuat d0(...)`) and used at line 482 in the same function. Cppcheck should never treat it as an incomplete or unknown variable. The new bailout shows that after the PR's template deduction and token-data update, the `d0` token lost its variable id or symbol. Cppcheck therefore understands this function worse: ValueFlow now skips it, where main did not report a bailout here. This is a new debug message caused by lost type information. ---- 46 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/s/sunpinyin/sunpinyin_3.0.0~rc2+ds1.orig.tar.xz Result: your sunpinyin-3.0.0-rc2/src/slm/tslmendian/writer.h:27:22: portability:inconclusive: Casting from float * to unsigned char * is not portable due to different binary data representations on different platforms. [invalidPointerCast] Explanation: The PR's new type deduction now instantiates `change_byte_order`, so `(uint8_t *)(&t)` is seen as a cast from `float *` to `unsigned char *`. Reading an object's bytes through `unsigned char *` is explicitly allowed by the standard. This template does it on purpose: its whole job is to reverse the byte order for endian conversion. The inconclusive portability warning flags intended, well-defined code and gives the user nothing to act on. The deduction itself looks correct, but this new warning is noise, effectively a false positive. ---- 47 / 50 ---- Verdict: REGRESSION (high confidence) Package: https://ftp.debian.org/debian/pool/main/w/worker/worker_5.3.1.orig.tar.bz2 Result: your worker-5.3.1/src/aguix/fieldlistview.h:486:7: warning: Member variable 'header_sort_hint::field' is not initialized in the constructor. [uninitMemberVar] Explanation: The constructor of header_sort_hint initializes 'field' in its member initializer list (field( -1 )). The new uninitMemberVar warning is therefore a false positive. It most likely comes from the PR's symbol database changes: createSymbolDatabaseNeedInitialization and copy/move constructor handling moved into finalize(), or symbols were removed or added incrementally, which leaves the constructor/initializer information wrong. ---- 48 / 50 ---- Verdict: IMPROVEMENT (high confidence) Package: https://ftp.debian.org/debian/pool/main/x/xmoto/xmoto_0.6.3+repack.orig.tar.xz Result: main xmoto-0.6.3/src/helpers/SwapEndian.cpp:23:54: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable _T [valueFlowBailoutIncompleteVar] Explanation: `SwapInPlace<_T>` is only reached through `SwapCopy(l)`, `SwapCopy(f)` and so on, which are called with variables, not literals. Main could not deduce template arguments from variables. The template therefore stayed uninstantiated, `_T` in `sizeof(_T)` was an incomplete variable, and ValueFlow skipped the function. With the PR, the template arguments are deduced from the argument ValueTypes. Concrete instantiations such as `SwapCopy` and `SwapInPlace` are created and the generic template is removed. The bailout disappears because Cppcheck now analyses the real instantiated code. ---- 49 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/z/zdbsp/zdbsp_1.19+20181027+dfsg.1.orig.tar.xz Result: main zdbsp-1.19+20181027+dfsg.1/blockmapbuilder.cpp:175:29: style: The scope of the variable 'block' can be reduced. [variableScope] Explanation: `block` and `endblock` are raw `TArray*` pointers declared at function scope in `BuildBlockmap`. In zdbsp they are only assigned and used inside the per-line `for` loop, so moving them into that loop is valid. The variableScope warning was therefore most likely a true positive. The PR has nothing to do with this check or with plain pointer variables; it only adds template type deduction and changes how the symbol database is built. The warning (and its twin for `endblock`) probably disappeared as a side effect of those changes, not because Cppcheck now understands the code better. Confidence is medium because the rest of the function body after line 215 is not shown. ---- 50 / 50 ---- Verdict: REGRESSION (low confidence) Package: https://ftp.debian.org/debian/pool/main/z/zdbsp/zdbsp_1.19+20181027+dfsg.1.orig.tar.xz Result: main zdbsp-1.19+20181027+dfsg.1/blockmapbuilder.cpp:175:37: style: The scope of the variable 'endblock' can be reduced. [variableScope] Explanation: `endblock` (like `block`) is declared at the top of `BuildBlockmap()` but is not used in the visible part of the function, which only works with `BlockLists`. Main reports both variables as variableScope, so they are most likely used only inside an inner block later on. That would make the warning a true positive. The PR does not change the variableScope check or how this code is written. Its changes are to template deduction and to updating the symbol database incrementally. So the lost warnings most likely come from Cppcheck understanding the function's variables worse, not from a fix. The later uses of `endblock` are not shown, so this cannot be confirmed.