AI review of 2026-10-21_14-55-28-255e8a3d38b0-results.txt PR: #8720 https://github.com/cppcheck-opensource/cppcheck/pull/8720 Tested: 255e8a3d38b0393fa677dfe833d2637ad8d35bb3 Merge base: 99ad2a83ab14c29d753272388b916887d936af03 Reviewed: 2026-10-22 13:21:04 UTC Model: claude-opus-5-5 (effort high) Results: 50 reviewed of 175 in the report (random sample), 3 not reviewed: valueFlowMaxIterations Verdicts: 20 improvement, 1 neutral, 27 regression, 2 unclear Tokens: 125856 input, 3170694 cache read, 696006 cache write, 41365 output The verdicts are written by AI and can be wrong. ---- 1 / 50 ---- Verdict: REGRESSION (high confidence) Package: https://ftp.debian.org/debian/pool/main/c/clazy/clazy_1.17.1.orig.tar.xz Result: your clazy-v1.17.1/src/ClazyContext.h:152:43: performance:inconclusive: Function parameter 'loc' should be passed by const reference. [passedByValue] Explanation: `isMainFile` takes `clang::SourceLocation loc` by value and then assigns to it (`loc = sm.getExpansionLoc(loc);`), so the parameter cannot be made a const reference. `SourceLocation` is also a tiny trivially copyable wrapper around an integer, so passing it by value is idiomatic. The new passedByValue warning is therefore a false positive. It suggests that after the PR's token and symbol database changes Cppcheck no longer sees the write to `loc` or the type correctly. ---- 2 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/d/dustrac/dustrac_2.2.0.orig.tar.gz Result: your DustRacing2D-2.2.0/src/game/MiniCore/src/Core/mcvector2d.hh:189:37: style:inconclusive: Function 'MCVector2d < U >' argument 2 names different: declaration 'j' definition 'newJ'. [funcArgNamesDifferent] DustRacing2D-2.2.0/src/game/MiniCore/src/Core/mcvector2d.hh:49:23: note: Function 'MCVector2d < U >' argument 2 names different: declaration 'j' definition 'newJ'. DustRacing2D-2.2.0/src/game/MiniCore/src/Core/mcvector2d.hh:189:37: note: Function 'MCVector2d < U >' argument 2 names different: declaration 'j' definition 'newJ'. Explanation: The parameter names really differ: the declaration at line 49 uses `i, j` and the definition at line 189 uses `newI, newJ`. But the warning names the function 'MCVector2d < U >'. `U` is an uninstantiated template parameter of the converting constructor/operator templates (lines 196-229), so the class was never instantiated with a type called `U`. The new type deduction apparently deduced a 'type' from an argument like `r` of type `MCVector2d` inside uninstantiated template code and created a bogus `MCVector2d` instantiation. Main did not report this, and the real instantiation (`MCVector2d`) does not produce it. The warning only appears because Cppcheck now misunderstands the template code, and the reported function name is wrong. ---- 3 / 50 ---- Verdict: REGRESSION (low confidence) Package: https://ftp.debian.org/debian/pool/main/d/dustrac/dustrac_2.2.0.orig.tar.gz Result: your DustRacing2D-2.2.0/src/game/MiniCore/src/Core/mcvector3d.hh:185:29: style:inconclusive: Function 'MCVector3d < U >' argument 1 names different: declaration 'i' definition 'newI'. [funcArgNamesDifferent] DustRacing2D-2.2.0/src/game/MiniCore/src/Core/mcvector3d.hh:52:18: note: Function 'MCVector3d < U >' argument 1 names different: declaration 'i' definition 'newI'. DustRacing2D-2.2.0/src/game/MiniCore/src/Core/mcvector3d.hh:185:29: note: Function 'MCVector3d < U >' argument 1 names different: declaration 'i' definition 'newI'. Explanation: The parameter names really do differ: the declaration at line 52 uses i/j/k and the definition at line 185 uses newI/newJ/newK, so the style finding itself is factually correct. However, main never reported this, and the new report names the function 'MCVector3d < U >'. That name is wrong: this is the constructor of MCVector3d, and U belongs only to the unrelated converting-constructor member templates. The name points to the new deduction and deferred-removal logic leaving a mangled or half-instantiated class template in the token list, which the checker then analyzes. So the warning likely comes from Cppcheck misunderstanding the code rather than a deliberate gain in coverage, and its message is inaccurate. ---- 4 / 50 ---- Verdict: UNCLEAR (low confidence) Package: https://ftp.debian.org/debian/pool/main/e/evolvotron/evolvotron_0.8.3.orig.tar.gz Result: your evolvotron-0.8.3/libfunction/function_node.h:149:40: warning: The class 'FunctionBoilerplate' defines member function with name 'create' also defined in its parent class 'FunctionNode'. [duplInheritedMember] Explanation: The new warning says that `FunctionBoilerplate`, a class template deriving from `FunctionNode`, defines a `create` member that hides the static `FunctionNode::create` declared at line 149. If the derived `create` has the same signature, as evolvotron's boilerplate factory likely does, the hiding is real, the warning is technically correct, and the hiding is probably intentional. However, the derived class source is not shown. The message names the plain template `FunctionBoilerplate` without template arguments. That suggests the generic template is now being analysed, possibly because the PR's deferred-removal or deduction logic left its declaration in place. From the given information it cannot be decided whether this is a valid new finding or an artifact of template handling. ---- 5 / 50 ---- Verdict: IMPROVEMENT (high confidence) Package: https://ftp.debian.org/debian/pool/main/f/ftgl/ftgl_2.4.0.orig.tar.xz Result: main ftgl-2.4.0/src/FTFont/FTFont.cpp:483:40: style:inconclusive: Function 'RenderI' argument 5 names different: declaration 'mode' definition 'renderMode'. [funcArgNamesDifferent] ftgl-2.4.0/src/FTFont/FTFontImpl.h:158:71: note: Function 'RenderI' argument 5 names different: declaration 'mode' definition 'renderMode'. ftgl-2.4.0/src/FTFont/FTFont.cpp:483:40: note: Function 'RenderI' argument 5 names different: declaration 'mode' definition 'renderMode'. Explanation: RenderI is a member function template declared in FTFontImpl.h with parameter name 'mode' and defined in FTFont.cpp with 'renderMode'. It is called as RenderI((const unsigned char*)string, ...) and RenderI(wchar_t-string, ...). The PR now deduces T from these non-literal arguments, so the template is instantiated as RenderI and RenderI. The generic 'RenderI' warning is replaced by one warning per instantiation. The warning is still valid, since the names really differ. Removing this 'main' line is part of a message rewrite, not a lost true positive. It shows Cppcheck now instantiates and analyses the template code, which is an improvement, even though the duplicated per-instantiation messages are somewhat noisier. ---- 6 / 50 ---- Verdict: NEUTRAL (medium confidence) Package: https://ftp.debian.org/debian/pool/main/f/ftgl/ftgl_2.4.0.orig.tar.xz Result: your ftgl-2.4.0/src/FTFont/FTOutlineFont.cpp:93:52: style:inconclusive: Function 'RenderI < char >' argument 1 names different: declaration 's' definition 'string'. [funcArgNamesDifferent] ftgl-2.4.0/src/FTFont/FTOutlineFontImpl.h:68:41: note: Function 'RenderI < char >' argument 1 names different: declaration 's' definition 'string'. ftgl-2.4.0/src/FTFont/FTOutlineFont.cpp:93:52: note: Function 'RenderI < char >' argument 1 names different: declaration 's' definition 'string'. Explanation: The template member function RenderI has a declaration with argument 's' and a definition with argument 'string'. Main reported this once for the generic template. With the PR, calls like RenderI(string, len, ...) are now deduced and instantiated as RenderI and RenderI, so the same warning is reported once per instantiation and the original 'RenderI' warning disappears. The finding is still correct, since the names really differ. It is now duplicated per instantiation and the name carries template arguments. That adds noise but no new information. Overall the result is roughly neutral, perhaps slightly worse because of the duplication. ---- 7 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/f/ftgl/ftgl_2.4.0.orig.tar.xz Result: your ftgl-2.4.0/src/FTFont/FTTextureFont.cpp:239:52: style:inconclusive: Function 'RenderI < char >' argument 1 names different: declaration 's' definition 'string'. [funcArgNamesDifferent] ftgl-2.4.0/src/FTFont/FTTextureFontImpl.h:147:41: note: Function 'RenderI < char >' argument 1 names different: declaration 's' definition 'string'. ftgl-2.4.0/src/FTFont/FTTextureFont.cpp:239:52: note: Function 'RenderI < char >' argument 1 names different: declaration 's' definition 'string'. Explanation: The header declares the member template `RenderI` with parameter `s`, and the out-of-line definition at line 239 names it `string`. So the funcArgNamesDifferent finding itself is a true positive. Main reported it once, as 'RenderI'. With the PR, the calls passing `const char*` and `const wchar_t*` are now deduced and instantiated. The same source-level issue is therefore reported twice at the same location, as 'RenderI < char >' and 'RenderI < wchar_t >'. No new real defect is found: the single warning about the template becomes per-instantiation duplicates. These name internal instantiations rather than the code the user wrote. That adds noise and makes the message less accurate. ---- 8 / 50 ---- Verdict: IMPROVEMENT (low confidence) Package: https://ftp.debian.org/debian/pool/main/g/gcc-h8300-hms/gcc-h8300-hms_3.4.6+dfsg2.orig.tar.gz Result: your gcc-h8300-hms-3.4.6+dfsg2/contrib/paranoia.cc:829:12: performance: Function parameter 'x' should be passed by const reference. [passedByValue] Explanation: The PR adds template argument deduction from argument types. A call such as `LOG(X)`, where `X` has a class type like `real_c_float`, can now be instantiated, so Cppcheck checks the body of `LOG`. In the active preprocessor branch, `x` is only read (`x.hex()`); the code that modifies it is under `#if 0`. Passing a class object by value just to read it is a valid performance hint, and `const FLOAT&` would also work for primitive instantiations. The warning appears to be a true positive from better template understanding. Some may dislike passedByValue on generic template code, and the actual deduced type is not shown, so confidence is low. ---- 9 / 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 body is entered when `obj == nullptr`. It first calls `checkHandle(obj)`, which throws when the handle is null. So `OIDN_LOCK(obj)` and `obj->destroy()` can only run with a non-null `obj`, and the nullPointerRedundantCheck warning was a false positive. With the PR, the calls to the template are now instantiated with deduced types, and the warning is gone. Removing a false positive helps users, though it may come from the changed instantiation rather than a deliberate fix for this pattern. ---- 10 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/g/godot3/godot3_3.6.2+ds.orig.tar.xz Result: your godotengine-godot-3cd3caa/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.cpp:137:57: style:inconclusive: Function 'gemm_s8x8s32' argument 9 names different: declaration 'lda' definition 'LDA'. [funcArgNamesDifferent] godotengine-godot-3cd3caa/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.hpp:36:57: note: Function 'gemm_s8x8s32' argument 9 names different: declaration 'lda' definition 'LDA'. godotengine-godot-3cd3caa/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.cpp:137:57: note: Function 'gemm_s8x8s32' argument 9 names different: declaration 'lda' definition 'LDA'. Explanation: The new warning reports a real difference. In mkl-dnn, gemm.hpp declares the function template `gemm_s8x8s32` with parameters `lda`, `ldb`, `c` and `ldc`. The definition in gemm.cpp uses `LDA`, `LDB`, `C` and `LDC`, and the reported columns match exactly (36:57 vs 137:57). Before the PR, the template declarations were probably removed after instantiation, so the check never compared them. The PR keeps the generic definition when calls without template arguments remain, so `funcArgNamesDifferent` now sees both and correctly reports the mismatch. The warning is factual, so this is a new true positive (style, inconclusive). ---- 11 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/g/godot3/godot3_3.6.2+ds.orig.tar.xz Result: your godotengine-godot-3cd3caa/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.cpp:138:35: style:inconclusive: Function 'gemm_s8x8s32' argument 12 names different: declaration 'ldb' definition 'LDB'. [funcArgNamesDifferent] godotengine-godot-3cd3caa/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.hpp:37:35: note: Function 'gemm_s8x8s32' argument 12 names different: declaration 'ldb' definition 'LDB'. godotengine-godot-3cd3caa/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.cpp:138:35: note: Function 'gemm_s8x8s32' argument 12 names different: declaration 'ldb' definition 'LDB'. Explanation: `gemm_s8x8s32` is a function template. gemm.hpp declares its parameters as `lda`, `ldb`, `c`, `ldc`, while gemm.cpp defines them as `LDA`, `LDB`, `C`, `LDC`. The names really do differ (by case), so this inconclusive style warning is a true positive. Main did not report it because the template was never instantiated. With the PR's type deduction the template is now instantiated, so the declaration/definition comparison runs. The locations point correctly at the original header and source lines. ---- 12 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/g/godot3/godot3_3.6.2+ds.orig.tar.xz Result: your godotengine-godot-3cd3caa/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.cpp:139:18: style:inconclusive: Function 'gemm_s8x8s32' argument 15 names different: declaration 'c' definition 'C'. [funcArgNamesDifferent] godotengine-godot-3cd3caa/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.hpp:38:18: note: Function 'gemm_s8x8s32' argument 15 names different: declaration 'c' definition 'C'. godotengine-godot-3cd3caa/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.cpp:139:18: note: Function 'gemm_s8x8s32' argument 15 names different: declaration 'c' definition 'C'. Explanation: `gemm_s8x8s32` is a function template. The header declares parameter 15 as `c`, and the definition in gemm.cpp:139 names it `C` (likewise `lda`/`LDA`, `ldb`/`LDB`, `ldc`/`LDC`). Main never instantiated the template, so `funcArgNamesDifferent` could not compare the declaration with the definition. The PR adds type deduction from non-literal call arguments, so the template is now instantiated and the check runs. The names really differ, and the reported locations (gemm.hpp:38:18 and gemm.cpp:139:18) point at the right parameter. This is a new true positive, albeit a minor style one. ---- 13 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/g/godot3/godot3_3.6.2+ds.orig.tar.xz Result: your godotengine-godot-3cd3caa/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.cpp:139:32: style:inconclusive: Function 'gemm_s8x8s32' argument 16 names different: declaration 'ldc' definition 'LDC'. [funcArgNamesDifferent] godotengine-godot-3cd3caa/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.hpp:38:32: note: Function 'gemm_s8x8s32' argument 16 names different: declaration 'ldc' definition 'LDC'. godotengine-godot-3cd3caa/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.cpp:139:32: note: Function 'gemm_s8x8s32' argument 16 names different: declaration 'ldc' definition 'LDC'. Explanation: `gemm_s8x8s32` is a function template whose parameter `b_dt` can only be deduced from the `const b_dt *B` argument. The PR adds type deduction from non-literal arguments, so calls of this template can now be instantiated, and the instantiation links the declaration in gemm.hpp with the definition in gemm.cpp. According to the warning's own notes, the declaration names argument 16 `ldc` and the definition names it `LDC`. That really is a parameter name mismatch, which is what funcArgNamesDifferent reports, so this is a new true positive from better template handling. The difference is only in letter case and the check is inconclusive/style, so it has limited value, but the message itself is accurate. ---- 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: your godotengine-godot-3cd3caa/thirdparty/oidn/mkl-dnn/src/cpu/gemm/gemm.cpp:205:46: warning: Potentially invalid type conversion in old-style C cast, clarify/fix with C++ cast [dangerousTypeCast] Explanation: Line 205 is inside the function template gemm_s8x8s32, where B has type 'const b_dt *'. The explicit instantiations below provide int8_t and uint8_t. With the PR, Cppcheck now instantiates the template and analyses the body with concrete types. In both instantiations the C-style cast '(int8_t *)B' drops the const qualifier. In the uint8_t instantiation it also reinterprets unsigned data as signed. Doing this with an old-style cast hides a const_cast/reinterpret_cast, which is exactly what dangerousTypeCast reports, so the new warning is a valid finding in template code that was not analysed before. ---- 15 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/g/graphite2/graphite2_1.3.15.orig.tar.gz Result: your graphite-1.3.15/src/inc/Main.h:13:1: debug: TemplateSimplifier: pass count limit hit before simplifications were finished. [debug] Explanation: The new debug message points at the first token of the file (namespace graphite2), not at any real code problem. It says the template simplifier ran all 10 passes without converging. The PR adds a second simplifyTemplates() run with type information and keeps instantiated declarations around (deferred removal), which likely keeps mChanged set on every pass. Graphite2 contains small helper templates (e.g. min/max-style functions in Main.h and TtfUtil). Before the PR the simplifier finished on this code; now it gives up, so Cppcheck understands the code worse. The new valueFlowMaxIterations messages in the same package point the same way. ---- 16 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/g/graphite2/graphite2_1.3.15.orig.tar.gz Result: your graphite-1.3.15/src/inc/TtfUtil.h:15:1: debug: TemplateSimplifier: pass count limit hit before simplifications were finished. [debug] Explanation: This new debug message says the template simplifier hit its pass count limit before it finished. That means Cppcheck handles this file's templates worse than before. The graphite2 sources use function templates such as be::swap / be::read, and the PR's new deduction with type information and deferred declaration removal seem to keep the simplifier changing the code in every pass. The reported location, a namespace start line, is just the first token of the file. Main did not report this, so the PR introduced the bailout. The new valueFlowMaxIterations debug messages in the same package point the same way. ---- 17 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/h/hyprtoolkit/hyprtoolkit_0.6.0.orig.tar.gz Result: your hyprwm-hyprtoolkit-f8cbaf4/src/element/LinearLayout.hpp:25:84: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable Horizontal [valueFlowBailoutIncompleteVar] Explanation: `Horizontal` is a non-type `bool` template parameter. It is used inside lambdas in the body of the function template `reposition`. That parameter cannot be deduced from call arguments, so the PR's deduction never applies to these calls. The new bailout means Cppcheck now runs ValueFlow on the uninstantiated generic body, where `Horizontal` is an unknown, incomplete name. Main did not report this. The likely cause is the PR's new 'keep the generic definition while plain calls remain' logic. It matches calls only by name, so an unrelated plain call such as a member `reposition(...)` would keep the template declaration in the token list. A new debug/bailout message about a template parameter shows the code is handled worse, not better. ---- 18 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/i/insighttoolkit4/insighttoolkit4_4.13.3withdata-dfsg2.orig.tar.gz Result: your insighttoolkit4-4.13.3withdata-dfsg2/Modules/IO/Bruker/src/itkBruker2dseqImageIO.cxx:114:5: style: The scope of the variable 'temp' can be reduced. [variableScope] Explanation: With the PR, Cppcheck can deduce T for calls like `ReverseSliceOrder(buffer, ...)` from the type of the argument, so this function template is now instantiated and checked. In `ReverseSliceOrder`, `temp` is declared at function scope but used only in the innermost loop. There it is always written (`temp = *toPixel`) before it is read, and its value is never carried between iterations. Moving the declaration into the inner loop is therefore valid, so the new variableScope warning is a true positive found thanks to better template handling. ---- 19 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/l/leocad/leocad_26.09.orig.tar.gz Result: main leozide-leocad-5196355/common/lc_objectproperty.cpp:26:31: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable T [valueFlowBailoutIncompleteVar] Explanation: The removed message is a ValueFlow bailout on the generic, uninstantiated body of `lcObjectPropertySaveValue`, where `T` in `sizeof(T)` is an incomplete variable. With the PR, calls such as `lcObjectPropertySaveValue(Stream, Value)` from the explicitly instantiated `lcObjectProperty` members can have `T` deduced from the argument types. The template gets concrete instantiations, and the generic declaration is removed once no undeduced calls remain. The bailout disappears because Cppcheck now analyzes concrete instantiations instead of the unknown-`T` body, not because analysis was lost. The same disappearance happens at line 53 for `lcObjectPropertyLoadValue`. ---- 20 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/l/leocad/leocad_26.09.orig.tar.gz Result: main leozide-leocad-5196355/common/lc_objectproperty.cpp:53:31: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable T [valueFlowBailoutIncompleteVar] Explanation: Line 53 is in the generic function template `lcObjectPropertyLoadValue`. It is called without explicit template arguments from `lcObjectProperty::Load`, and those members are explicitly instantiated for float, lcVector2, lcVector3 and other types. Main could not deduce T from non-literal arguments, so the template body stayed uninstantiated. ValueFlow then skipped it with a debug bailout on the incomplete variable T. With the PR's type-based deduction, the calls are deduced and concrete instantiations are created. The generic template body is removed, so the bailout goes away. Cppcheck now analyzes concrete instantiations instead of skipping the code. ---- 21 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/l/leocad/leocad_26.09.orig.tar.gz Result: your leozide-leocad-5196355/common/lc_model.cpp:2131:8: style: Consider using std::accumulate algorithm instead of a raw loop. [useStlAlgorithm] Explanation: The loop `Step = lcMax(Step, Piece->GetStepShow());` folds every element into one accumulator, which is exactly the pattern useStlAlgorithm targets. It can be rewritten as `std::accumulate` with a lambda that calls `lcMax`. `lcMax` is a function template. Before the PR the call `lcMax(Step, ...)` was not instantiated, so cppcheck treated it as an unknown call that might have side effects and stayed silent. With type deduction it is now instantiated and resolved, so the check can see it is a pure accumulation. The new warning is a valid style suggestion that comes from cppcheck understanding the code better, not a false positive. `std::max_element` might be the nicer advice, but `lcMax` is not `std::max`, so suggesting `std::accumulate` is acceptable. ---- 22 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/l/ltt-control/ltt-control_2.16.0.orig.tar.bz2 Result: your lttng-tools-2.16.0/src/vendor/fmt/format.h:1784:28: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable Char [valueFlowBailoutIncompleteVar] Explanation: The new bailout is reported inside the generic `find_escape` template, where `Char` is an unresolved template parameter. Before the PR, the template declaration was removed after instantiation (`find_escape` is explicitly instantiated), so this generic body was never analyzed. The PR now keeps a template declaration when plain undeduced calls like `find_escape(begin, end)` remain. Here such calls exist because a non-template `const char*` overload blocks deduction. As a result, the raw template body with unknown types survives into ValueFlow and causes a new bailout message. This adds noise and shows Cppcheck processing code it cannot understand, without any gain in analysis. ---- 23 / 50 ---- Verdict: REGRESSION (high confidence) Package: https://ftp.debian.org/debian/pool/main/libe/libe57format/libe57format_3.4.0.orig.tar.gz Result: your asmaloney-libE57Format-9c16b96/src/SourceDestBufferImpl.cpp:947:28: style: Either there is a missing 'override', or the member function 'e57::SourceDestBufferImpl::setNextDouble' can be static. [functionStatic] asmaloney-libE57Format-9c16b96/src/SourceDestBufferImpl.h:110:12: note: Either there is a missing 'override', or the member function 'e57::SourceDestBufferImpl::setNextDouble' can be static. asmaloney-libE57Format-9c16b96/src/SourceDestBufferImpl.cpp:947:28: note: Either there is a missing 'override', or the member function 'e57::SourceDestBufferImpl::setNextDouble' can be static. Explanation: setNextDouble() calls `_setNextReal(value)`, a member function template that reads and writes members such as `nextIndex_`, `pathName_` and `doConversion_`. So setNextDouble() uses `this` and cannot be static. With the PR, the call is deduced and renamed to `_setNextReal`. The functionStatic check then apparently no longer recognises it as a call to a non-static member, probably because the new instantiation is not linked correctly in the incrementally updated symbol database. The new warning is a false positive. ---- 24 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/libm/libmwaw/libmwaw_0.3.23.orig.tar.xz Result: your libmwaw-0.3.23/src/lib/libmwaw_internal.hxx:167:13: warning: Comparison of a boolean expression with an integer. [compareBoolExpressionWithInt] Explanation: `checkAddOverflow` is a generic overflow helper in which `x < 0` is a normal comparison for numeric T. The new warning means the PR's type deduction instantiated the template with T = bool. That is either a wrong deduction or a rare bool call site. Either way, flagging `x < 0` inside generic template code because of one instantiation is noise, not a real bug in this line, so this is a likely false positive. ---- 25 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/libs/libsbsms/libsbsms_2.3.0.orig.tar.gz Result: your libsbsms-2.3.0/src/buffer.h:157:8: warning: Class 'ArrayRingBuffer' does not have a operator= which is recommended since it has dynamic memory/resource management. [noOperatorEq] Explanation: ArrayRingBuffer allocates `buf` with calloc in its constructor, reallocates it in grow(), and frees it in its destructor. It declares no copy assignment operator, so the implicit operator= does a shallow pointer copy, which leads to a double free or leak. The noOperatorEq warning is therefore a true positive. The PR most likely exposes it by changing how template instantiations and symbol database finalization are done. ---- 26 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/libs/libstxxl/libstxxl_1.4.1.orig.tar.gz Result: main stxxl-1.4.1/tests/algo/test_sort_all_parameters.h:23:5: warning: Member variable 'bulk < 0 >::m_data' is not initialized in the constructor. [uninitMemberVar] Explanation: The warning is about 'bulk < 0 >::m_data', but `bulk<0>` is an explicit specialization (lines 31-33) that has no members at all. Main wrongly instantiated the primary template with n=0, which produced a phantom `m_data` member. That same error explains the ctuOneDefinitionRuleViolation for 'bulk < 0 >', which also disappeared with this PR. The removed uninitMemberVar was therefore a false positive caused by the bad instantiation. ---- 27 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/libs/libstxxl/libstxxl_1.4.1.orig.tar.gz Result: main stxxl-1.4.1/tests/algo/test_sort_all_parameters.h:32:1: error: The one definition rule is violated, different classes/structs have the same name 'bulk < 0 >' [ctuOneDefinitionRuleViolation] stxxl-1.4.1/tests/algo/test_sort_all_parameters.h:19:1: note: The one definition rule is violated, different classes/structs have the same name 'bulk < 0 >' stxxl-1.4.1/tests/algo/test_sort_all_parameters.h:32:1: note: The one definition rule is violated, different classes/structs have the same name 'bulk < 0 >' Explanation: `bulk<0>` is an explicit specialization (line 32) of the primary template `bulk` (line 19). In real C++ only one definition of `bulk<0>` exists: the empty specialization. Main wrongly instantiated the primary template with n=0 as well, which produced two classes named 'bulk < 0 >'. That gave this false ctuOneDefinitionRuleViolation. It also gave the uninitMemberVar warning about `bulk<0>::m_data`, a member that does not exist in the specialization, and that warning was removed too. The PR removes the bogus ODR report, so a false positive is gone. ---- 28 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/libs/libstxxl/libstxxl_1.4.1.orig.tar.gz Result: your stxxl-1.4.1/examples/applications/skew3.cpp:1203:45: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable offset_type [valueFlowBailoutIncompleteVar] Explanation: Line 1203 is in the generic body of `template int process(...)`. `offset_type` is the template parameter and cannot be deduced from the function arguments, so `process` must be called with explicit template arguments and gets instantiated. Main did not report this, which means the generic template had been instantiated and removed from the token list. With the PR, the generic declaration is apparently kept. The likely cause is the new deferred-removal / `hasRemainingCalls` logic, whose loose `isPlainCall` matching may treat some other `process(` token as an undeduced call. Cppcheck then analyses the uninstantiated template body and bails out on the incomplete variable `offset_type`. A new debug bailout caused by leftover uninstantiated template code shows Cppcheck now handles this code worse. ---- 29 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/libz/libzypp/libzypp_17.38.16.orig.tar.gz Result: your libzypp-17.38.16/zypp/zypp/ng/workflows/checksumwf.cc:33: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 CheckSumWorkflowLogic. The code is unchanged and was handled without this message before. The PR adds type-information template deduction rounds that update or rebuild the symbol database incrementally, and it moves several symbol database phases into finalize(). That likely leaves some type pointers unresolved in this class, which uses nested aliases like Context::ProvideType, member templates and lambdas. Similar new messages appear in keyringwf.cc and signaturecheckwf.cc, which points to a systematic loss of type resolution. A new debug message of this kind means Cppcheck understands the code worse. ---- 30 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/libz/libzypp/libzypp_17.38.16.orig.tar.gz Result: your libzypp-17.38.16/zypp/zypp/ng/workflows/keyringwf.cc:27:3: debug: SymbolDatabase couldn't resolve all user defined types. [debug] Explanation: This debug message is new in the PR. It is reported at the `ImportKeyFromRepoLogic` struct, which uses type aliases built from `Context::ProvideType` and declares member functions with unresolved user-defined types. Main resolved these types without complaint. The PR's new type-deduction rounds and incremental symbol database updates (adding and removing scopes and types, clearing type pointers) leave some types unresolved here. A new debug message means Cppcheck understands this code worse, which is a regression. The same message also appears in several other workflow files of this package. ---- 31 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/m/memkind/memkind_1.14.0.orig.tar.xz Result: main memkind-1.14.0/test/heap_manager_init_perf_test.cpp:21:25: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable total_time [valueFlowBailoutIncompleteVar] Explanation: `total_time` is a member of the struct returned by `initialize_allocator(...)`, not an unknown variable, so the old `valueFlowBailoutIncompleteVar` was spurious. The PR moves `createSymbolDatabaseIncompleteVars()` into `finalize()`, which now runs after value types and variable pointers have been set. The member access after the call has most likely been resolved by then, so it is no longer flagged as incomplete. The function is no longer skipped by ValueFlow, which is a small improvement. Confidence is medium because it depends on the project header being parsed. ---- 32 / 50 ---- Verdict: REGRESSION (high confidence) Package: https://ftp.debian.org/debian/pool/main/m/mpd/mpd_0.24.16.orig.tar.xz Result: your mpd-0.24.16/src/lib/curl/Easy.hxx:74:7: style: The member function 'CurlEasy::SetOption' can be static. [functionStatic] Explanation: SetOption calls the member template TrySetOption, which uses the member 'handle' through curl_easy_setopt(handle, ...). So SetOption depends on the object and cannot be static. The new type deduction instantiates SetOption, but the TrySetOption call inside the instantiated body is apparently no longer resolved as a member function call. Cppcheck therefore wrongly thinks SetOption uses no members. This new functionStatic warning is a false positive. ---- 33 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/n/ncbi-igblast/ncbi-igblast_1.20.0.orig.tar.gz Result: your ncbi-igblast-1.20.0-src/c++/src/util/checksum/farmhash/farmhash.cc:393:24: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable c1 [valueFlowBailoutIncompleteVar] Explanation: The PR now deduces the template arguments of calls such as `DebugTweak(Uint128Low64(x))` and instantiates `DebugTweak`. In the instantiated body (line 393), `c1` is not resolved to the `static const uint32_t c1` declared a few lines above in the same namespace. Its declaration is plainly visible, so `c1` should have a variable id and symbol. Because it does not, ValueFlow skips the whole function with an incomplete-variable bailout. The new token data (variable id or symbol binding) for the generated instantiation is evidently incomplete. A new bailout caused by a failure to resolve a known variable means Cppcheck understands this code worse. ---- 34 / 50 ---- Verdict: REGRESSION (low confidence) Package: https://ftp.debian.org/debian/pool/main/n/nexus/nexus_4.4.3.orig.tar.gz Result: your code-4.4.3/applications/NXtranslate/tree.hh:1032:0: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable sibling_iterator [valueFlowBailoutIncompleteVar] Explanation: The PR adds a new valueFlowBailoutIncompleteVar debug message for `merge()` in the `tree` class template. `sibling_iterator` is a nested type of `tree`, used in the parameter list of the out-of-line member function `tree::merge`. A correct symbol database would resolve it as a type, not treat it as an unknown variable. With this message, ValueFlow condition analysis is skipped for the whole function. The PR moves `createSymbolDatabaseIncompleteVars` into `finalize()` and changes template instantiation, which plausibly causes this. The new operatorEqVarError for the instantiated `tree` suggests more instantiation now happens, so this could partly reflect newly analysed code. Still, the new bailout itself shows Cppcheck understands this function worse. ---- 35 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/n/nexus/nexus_4.4.3.orig.tar.gz Result: your code-4.4.3/applications/NXtranslate/tree.hh:430:36: warning:inconclusive: Member variable 'tree < Node , std :: allocator < tree_node_ < Node > > >::alloc_' is not assigned a value in 'tree < Node , std :: allocator < tree_node_ < Node > > >::operator='. [operatorEqVarError] Explanation: The PR makes Cppcheck instantiate `tree>>`, and the new inconclusive warning comes from that instantiation. `operator=` calls `copy_()`, which deep-copies the nodes through `head` and `feet`. The member `alloc_` is a stateless `std::allocator`, so leaving it unassigned in copy assignment is normal and has no effect; standard containers likewise do not always propagate allocators on copy assignment. The warning is technically literal but practically a false positive, so the new report is noise for users. ---- 36 / 50 ---- Verdict: REGRESSION (low confidence) Package: https://ftp.debian.org/debian/pool/main/n/nexus/nexus_4.4.3.orig.tar.gz Result: your code-4.4.3/applications/NXtranslate/tree.hh:468:0: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable pre_order_iterator [valueFlowBailoutIncompleteVar] Explanation: Line 468 is in `tree::clear()`. It builds a temporary `pre_order_iterator(head->next_sibling)`, and `pre_order_iterator` is a nested iterator class of `tree`. The PR adds a new valueFlowBailoutIncompleteVar there, so the nested type name is not resolved as a type and ValueFlow skips the whole function. The new operatorEqVarError for `tree` suggests the class template is now instantiated, probably through a deduced call. Even so, the nested type of the instantiation is not resolved. A new bailout like this means Cppcheck understands the code worse. It may be a side effect of newly instantiated code rather than a direct loss, hence low confidence. ---- 37 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/n/nexus/nexus_4.4.3.orig.tar.gz Result: your code-4.4.3/applications/NXtranslate/tree.hh:890:0: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable pre_order_iterator [valueFlowBailoutIncompleteVar] Explanation: This new debug bailout appears in `tree::replace`, at the line `pre_order_iterator tt=insert_subtree(...)`. It shows up together with other new messages that name the instantiated class `tree < Node , std :: allocator < ... > >`. So the PR's type-deduction rounds now produce an instantiation of the tree class. In that copy, ValueFlow cannot resolve the nested type `pre_order_iterator` and treats it as an incomplete variable, so it skips the function. The code is valid: `pre_order_iterator` is a nested type of `tree`. A new valueFlowBailoutIncompleteVar means Cppcheck understands this code worse after the PR. ---- 38 / 50 ---- Verdict: IMPROVEMENT (low confidence) Package: https://ftp.debian.org/debian/pool/main/n/ns3/ns3_3.48.orig.tar.bz2 Result: main ns-3.48/src/wifi/model/rate-control/minstrel-ht-wifi-manager.cc:602:14: debug: valueFlowConditionExpressions bailout: Skipping function due to incomplete variable numRateAttempt [valueFlowBailoutIncompleteVar] Explanation: The removed message is a debug bailout for `station->m_groupsTable[groupId].m_ratesTable[rateId].numRateAttempt++`. `numRateAttempt` is an ordinary struct member, so main flagging it as an incomplete variable was a limitation, not a real problem in the code. The PR reworks template handling and runs `createSymbolDatabaseIncompleteVars` later, in `finalize()`. All five bailouts in this file (`numRateAttempt`, `numRateSuccess`, `mcsIndex`) disappear together. No new error or bailout appears for the file, so ValueFlow no longer skips these functions and most likely now understands the member accesses. The cause cannot be confirmed from the information shown, hence low confidence. ---- 39 / 50 ---- Verdict: REGRESSION (high confidence) Package: https://ftp.debian.org/debian/pool/main/p/paraview/paraview_6.1.1+dfsg1.orig.tar.gz Result: your Remoting/ServerManager/vtkSMPropertyHelper.cxx:756:27: style: The member function 'vtkSMPropertyHelper::Append' can be static. [functionStatic] Remoting/ServerManager/vtkSMPropertyHelper.h:116:8: note: The member function 'vtkSMPropertyHelper::Append' can be static. Remoting/ServerManager/vtkSMPropertyHelper.cxx:756:27: note: The member function 'vtkSMPropertyHelper::Append' can be static. Explanation: `Append` calls `this->AppendPropertyArray(values, count)`, a non-static member template of `vtkSMPropertyHelper` that works on the helper's property state. Because the call goes through `this` to a member function, `Append` cannot be static. The PR now deduces the template argument (`AppendPropertyArray`), and the instantiated call is apparently no longer recognized as a member call. The new functionStatic warning is therefore a false positive. ---- 40 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/p/protobuf2/protobuf2_2.6.1.orig.tar.gz Result: main protobuf-2.6.1/gtest/test/gtest-printers_test.cc:963:8: style: struct member 'iterator::x' is never used. [unusedStructMember] Explanation: `struct iterator { char x; }` is zero-initialized and passed whole to the gtest template `Print(it)`, which dumps the object's raw bytes. The test expects "1-byte object <00>", so `x` is read through that byte dump. The member is not dead even though it is never named. With the PR, `Print(it)` is now deduced and instantiated as `Print`, so Cppcheck sees the struct passed to a real function and drops the warning. The same change happens consistently for `const_iterator`. Removing this likely false positive is an improvement. ---- 41 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/p/protobuf2/protobuf2_2.6.1.orig.tar.gz Result: main protobuf-2.6.1/gtest/test/gtest-printers_test.cc:974:8: style: struct member 'const_iterator::x' is never used. [unusedStructMember] Explanation: `const_iterator::x` is never accessed by name, but the whole object is passed to gtest's `Print(it)`. `Print` dumps the object's bytes, and the test expects `"1-byte object <00>"`. The member is what gives the struct its zero-initialized byte contents, so it is effectively used and the warning was a false positive. With the PR, cppcheck deduces the template argument of `Print(it)` (now `Print`) and instantiates it. The struct is then seen as used through that generic code, so the unusedStructMember check no longer flags it. The same happens for the sibling `iterator::x`, so the change is consistent. ---- 42 / 50 ---- Verdict: UNCLEAR (low confidence) Package: https://ftp.debian.org/debian/pool/main/q/qt3d-opensource-src/qt3d-opensource-src_5.15.19+dfsg.orig.tar.xz Result: your qt3d-everywhere-src-5.15.19/src/render/backend/uniform_p.h:200:16: style: Local variable 'data' shadows outer function [shadowFunction] qt3d-everywhere-src-5.15.19/src/render/backend/uniform_p.h:215:8: note: Shadowed function qt3d-everywhere-src-5.15.19/src/render/backend/uniform_p.h:200:16: note: Shadow local variable Explanation: In `setData()`, the local `float *data` does hide the member function template `data()` declared at line 215, so the new shadowFunction warning is technically correct. The likely cause, though, is unrelated to better understanding. The PR's new `hasRemainingCalls()`/`isPlainCall()` appears to treat `m_data.data()` (a call on a QVarLengthArray) as a remaining call of the template `data`. So the generic `data` declaration is kept instead of removed, and the check now sees it. The same pattern in the constructor at line 170 is still not reported, so the output is inconsistent. A side effect of over-conservative template retention, of doubtful value to users. ---- 43 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/q/qtdeclarative-opensource-src-gles/qtdeclarative-opensource-src-gles_5.15.19+dfsg.orig.tar.xz Result: your qtdeclarative-everywhere-src-5.15.19/src/qml/compiler/qv4compilercontext_p.h:180:5: 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 the plain struct `Context::Member`. Main does not report it for this code. This message is normally emitted when need-initialization analysis cannot resolve the member types. Here those are an enum `QQmlJS::AST::VariableScope` and the class `QQmlJS::SourceLocation`. The PR moved createSymbolDatabaseNeedInitialization into finalize(), which runs after the new template-deduction rounds and their incremental symbol database updates. Type resolution for this struct is now worse, so later checks such as uninitMemberVar get less information about it. ---- 44 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/q/qtdeclarative-opensource-src-gles/qtdeclarative-opensource-src-gles_5.15.19+dfsg.orig.tar.xz Result: your qtdeclarative-everywhere-src-5.15.19/src/qml/compiler/qv4compilercontext_p.h:243:5: 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 the nested class template `SmallSet : public QVarLengthArray`. The code did not change, so this comes from the PR's new template type-deduction rounds. These rounds rebuild or incrementally update the symbol database, and afterwards a user-defined type (here the class template's base) is no longer resolved. The same message appears at two other places in this header. A new debug message on unchanged code means Cppcheck now understands the code worse (or the rebuild path is less complete), which counts as a regression. ---- 45 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/q/qtdeclarative-opensource-src-gles/qtdeclarative-opensource-src-gles_5.15.19+dfsg.orig.tar.xz Result: your qtdeclarative-everywhere-src-5.15.19/src/qml/compiler/qv4compilercontext_p.h:336:5: 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 the nested struct ResolvedName (it has a nested enum Type and a member of that type). The same message also appears at two other class scopes in this header. Main resolved these types without complaint. Nothing in this code involves function template deduction, so the message is most likely a side effect of the PR's symbol database changes: the rebuild or incremental update after template deduction, and phases moved into finalize(). A new debug message means Cppcheck understands the code worse. ---- 46 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/s/scribus/scribus_1.6.6+dfsg.orig.tar.xz Result: your scribus-1.6.6+dfsg/scribus/styles/paragraphstyle.cpp:366:22: warning: The class 'ParagraphStyle' defines member function with name 'desaxeRules' also defined in its parent class 'BaseStyle'. [duplInheritedMember] scribus-1.6.6+dfsg/scribus/styles/style.h:16:17: note: Parent function 'BaseStyle::desaxeRules' scribus-1.6.6+dfsg/scribus/styles/paragraphstyle.cpp:366:22: note: Derived function 'ParagraphStyle::desaxeRules' Explanation: `BaseStyle::desaxeRules` is a static member function template (`template`). `ParagraphStyle` deliberately provides its own static `desaxeRules` and calls the base version explicitly as `BaseStyle::desaxeRules(...)`. This is an intended name-hiding pattern, not an accidental duplicate. Main did not warn because the generic template declaration was removed once it was instantiated. With the PR, the generic declaration is kept when calls to that name remain without template arguments, and that test is by name only. There is such a call, `CharStyle::desaxeRules(stylePrefix, ruleset)`, but it belongs to an unrelated class. The leftover template is then treated as an ordinary parent function and matched against the derived function. The new warning is an artifact of leftover template tokens and is noise for users. ---- 47 / 50 ---- Verdict: IMPROVEMENT (medium confidence) Package: https://ftp.debian.org/debian/pool/main/s/scribus/scribus_1.6.6+dfsg.orig.tar.xz Result: your scribus-1.6.6+dfsg/scribus/third_party/lib2geom/path.cpp:105:5: performance: Prefer prefix ++/-- operators for non-primitive types. [postfixOperator] Explanation: `inc(begin(), n)` is called with a `Path::const_iterator`, which is a class-type iterator. With the PR, Cppcheck deduces the template argument from the type of `begin()` and instantiates `inc`. It can then see that `ret++` is a postfix increment on a class object whose result is discarded. Prefix `++ret` would avoid creating a temporary copy, so the new postfixOperator warning is a valid, if minor, true positive. ---- 48 / 50 ---- Verdict: REGRESSION (medium confidence) Package: https://ftp.debian.org/debian/pool/main/s/svgpp/svgpp_1.3.1+dfsg1.orig.tar.xz Result: your svgpp-1.3.1+dfsg1/src/test/full_parse_test_common.hpp:33:21: style: Variable 'val' is assigned a value that is never used. [unreadVariable] Explanation: `UseValue` deliberately stores the argument in a `volatile static T val` so the compiler cannot optimize the value away, as the comment says. A write to a volatile object is an observable side effect, so warning that the value is never used is a false positive. Main saw only the generic template, where `T` is unknown, and stayed silent. The PR's new type deduction instantiates `UseValue` from the `UseValue(value)` calls with a concrete type. The unreadVariable check then fires on the instantiated copy without taking `volatile` (and static) into account. ---- 49 / 50 ---- Verdict: REGRESSION (high confidence) Package: https://ftp.debian.org/debian/pool/main/z/zimlib/zimlib_8.1.1.orig.tar.gz Result: your libzim-8.1.1/src/debug.h:41:22: warning: Null pointer dereference: a [ctunullpointer] libzim-8.1.1/src/file_reader.cpp:102:5: note: Assignment '_right=0U', assigned value is 0 libzim-8.1.1/src/file_reader.cpp:102:5: note: Assuming that condition '(_left)>(_right)' is not redundant libzim-8.1.1/src/file_reader.cpp:102:5: note: Calling function _on_assert_fail, 4th argument is null libzim-8.1.1/src/debug.h:41:22: note: Dereferencing argument a that is null Explanation: `_on_assert_fail` takes `a` and `b` by value. The ASSERT macro passes `auto _left` and `auto _right`, and the trace shows these are integers (`_right=0U`). The function only streams them with `ss << a`. Streaming an integer 0 is not a pointer dereference, so 'Null pointer dereference: a' is a false positive. It appears only after the PR's new type deduction instantiates the template, and the trace even mixes up the 4th argument (`a`) with `_right`. Cppcheck's analysis of the deduced instantiation is wrong here. ---- 50 / 50 ---- Verdict: REGRESSION (high confidence) Package: https://ftp.debian.org/debian/pool/main/z/zimlib/zimlib_8.1.1.orig.tar.gz Result: your libzim-8.1.1/src/debug.h:41:63: error: Null pointer dereference: b [ctunullpointer] libzim-8.1.1/src/compression.cpp:132:7: note: Assignment '_right=0u', assigned value is 0 libzim-8.1.1/src/compression.cpp:132:7: note: Assuming condition is true libzim-8.1.1/src/compression.cpp:132:7: note: Calling function _on_assert_fail < unsigned long , unsigned int >, 5th argument is null libzim-8.1.1/src/debug.h:41:63: note: Dereferencing argument b that is null Explanation: The ASSERT macro does `auto _right = 0u`, so `_right` is an `unsigned int`. It is passed by value to `_on_assert_fail`, and parameter `b` is an unsigned int that is only streamed with `<< b`. Printing an integer 0 is not a pointer dereference, so 'Null pointer dereference: b' is wrong. The PR's new type deduction instantiated the template, and that instantiation exposed the CTU null-pointer check to an integer parameter. This is a new false positive.