Is there a clang-tidy check for returning a non-const reference from a const getter?

89 views Asked by At

I would like to check our code for developers returning non-const reference in const methods. Under normal circumstances a compiler would catch it, but if using PIMPL or pointers things get a little weird.

An example of how this is possible:

#include <cstdint>
#include <iostream>
#include <memory>
#include <vector>

struct PIMPL
{

    int x = 0;
};

struct Data
{
    std::unique_ptr<PIMPL> m_pimpl = std::make_unique<PIMPL>();

    // Signature is physically const correct, but logically const broken
    int& func() const
    {
        return m_pimpl->x;
    }

    int& func()
    {
        return m_pimpl->x;
    }
};

int main(int argc, char* argv[])
{
    Data dat1;
    const Data dat2;


    // OK
    dat1.func() = 2;
    // this should not be possible in the API
    dat2.func() = 44;

    std::cout << dat1.func() << std::endl;
    std::cout << dat2.func() << std::endl;

}

This is also valid in some weird edge cases. I can see someone wanting to have a mutable field on a const class that uses pimpl, but would expect them to explicitly mark the field in the pimpl struct as mutable to clarify it even if it is not physically necessary.

After some searching on google and reading the docs I don't see an option in the clang-tidy documentation for this which surprises me.

In my mind it should be a check of:

  • member function is const qualified
  • is returning a reference type token
  • return token is not const qualified
  • if returning a member of something, that member is not marked mutable
0

There are 0 answers