Affected rules
Description
The cpp/misra/unused-limited-visibility-function (RULE-0-2-4) and cpp/autosar/unused-local-function (A0-1-3) queries report false positives for private member functions that are genuinely used. We found 57 false-positive findings out of 58 total on the eclipse-score/communication codebase.
The false positives fall into three distinct categories.
Category 1: Private methods called through friend class access
The query does not reliably resolve call sites that go through friend-class access.
Example
class SharedMemoryResource {
friend class SharedMemoryFactoryImpl;
private:
static cpp::expected<std::shared_ptr<SharedMemoryResource>, os::Error> Create(...) noexcept;
static cpp::expected<std::shared_ptr<SharedMemoryResource>, os::Error> Open(...) noexcept;
uid_t getOwnerUid() const noexcept;
};
Create, Open, and getOwnerUid are all called from SharedMemoryFactoryImpl (a declared friend), but the query flags them as unused.
Category 2: Private template helpers / constructors only called via direct static dispatch
The query uses getTarget(call) from DynamicCallGraph, which resolves virtual dispatch. For non-virtual private methods or private template helpers called directly, the dynamic target may not be resolved, so the call goes unrecognised.
Example 1 – private delegating constructor:
template <typename FieldType, typename... Tags>
class ProxyFieldImpl {
public:
ProxyFieldImpl(ProxyBase& proxy_base, std::string_view field_name)
: ProxyFieldImpl{field_name,
MakeSetMethodDispatchIfEnabled(proxy_base, field_name), // called here
MakeGetMethodDispatchIfEnabled(proxy_base, field_name)} // called here
{}
private:
static std::unique_ptr<ProxyMethod<SetMethodSignature<FieldType>>>
MakeSetMethodDispatchIfEnabled(ProxyBase&, std::string_view); // flagged as unused
static std::unique_ptr<ProxyMethod<GetMethodSignature<FieldType>>>
MakeGetMethodDispatchIfEnabled(ProxyBase&, std::string_view); // flagged as unused
};
Example 2 – singleton accessor pattern:
template <typename SampleType>
class ProxyEventBindingFactory {
public:
static auto Create(...) { return instance().Create(...); } // calls instance()
private:
static IProxyEventBindingFactory<SampleType>& instance() noexcept; // flagged as unused
};
Category 3: Pure virtual private member declarations
Pure virtual functions (= 0) are interface contracts that derived classes must override. They have no definition body and cannot be "called" directly. The query incorrectly includes them as candidates.
Example:
class ManagedMemoryResource {
private:
virtual const void* getEndAddress() const noexcept = 0; // flagged
virtual const MemoryResourceProxy* getMemoryResourceProxy() noexcept = 0; // flagged
};
class SkeletonFieldBase {
private:
virtual Result<void> DoDeferredUpdate() noexcept = 0; // flagged
};
class IMessagePassingService {
private:
virtual void UnregisterMethodCallHandler(QualityType, ProxyMethodInstanceIdentifier) = 0; // flagged
};
Expected behavior
The query should only flag private / limited-visibility functions that are genuinely never called. It should not flag:
- Private members invoked from friend classes.
- Private helper functions that appear as direct static call targets.
- Pure virtual member declarations (
= 0).
Affected queries
cpp/misra/unused-limited-visibility-function (RULE-0-2-4)
cpp/autosar/unused-local-function (A0-1-3)
Both share cpp/common/src/codingstandards/cpp/rules/unusedlocalfunction/UnusedLocalFunction.qll.
Environment
- CodeQL bundle:
codeql-bundle-v2.21.4
- Coding standards pack:
2.61.0
- Downstream repo:
eclipse-score/communication
Affected rules
Description
The
cpp/misra/unused-limited-visibility-function(RULE-0-2-4) andcpp/autosar/unused-local-function(A0-1-3) queries report false positives for private member functions that are genuinely used. We found 57 false-positive findings out of 58 total on theeclipse-score/communicationcodebase.The false positives fall into three distinct categories.
Category 1: Private methods called through
friend classaccessThe query does not reliably resolve call sites that go through friend-class access.
Example
Create,Open, andgetOwnerUidare all called fromSharedMemoryFactoryImpl(a declared friend), but the query flags them as unused.Category 2: Private template helpers / constructors only called via direct static dispatch
The query uses
getTarget(call)fromDynamicCallGraph, which resolves virtual dispatch. For non-virtual private methods or private template helpers called directly, the dynamic target may not be resolved, so the call goes unrecognised.Example 1 – private delegating constructor:
Example 2 – singleton accessor pattern:
Category 3: Pure virtual private member declarations
Pure virtual functions (
= 0) are interface contracts that derived classes must override. They have no definition body and cannot be "called" directly. The query incorrectly includes them as candidates.Example:
Expected behavior
The query should only flag private / limited-visibility functions that are genuinely never called. It should not flag:
= 0).Affected queries
cpp/misra/unused-limited-visibility-function(RULE-0-2-4)cpp/autosar/unused-local-function(A0-1-3)Both share
cpp/common/src/codingstandards/cpp/rules/unusedlocalfunction/UnusedLocalFunction.qll.Environment
codeql-bundle-v2.21.42.61.0eclipse-score/communication