c++mpivoid-pointersclang-tidyindirection

How to fix "multi level implicit pointer conversion" warning in clang-tidy?


I have some legacy code that reads like this:

bool has_attribute(int kvidx) const {
    void* v = nullptr;
    int flag = 0;
    MPI_Comm_get_attr(impl_, kvidx, &v, &flag);
    return flag != 0;
}

The third argument of MPI_Comm_get_attr takes a void**.

CORRECTION: … it takes void*, but it is void** semantically according to the function documentation. This is the true origin of the warning.

This code now is giving a clang-tidy warning bugprone-multi-level-implicit-pointer-conversion.

https://releases.llvm.org/18.1.0/tools/clang/tools/extra/docs/clang-tidy/checks/bugprone/multi-level-implicit-pointer-conversion.html

Clang-tidy recommends: "multilevel pointer conversion from 'char **' to 'void *', please use explicit cast"

How do I apply this "explicit cast"?

I tried with MPI_Comm_get_attr(impl_, kvidx, static_cast<void**>(&v), &flag); but clang is still complaining.

To be clear, the code is correct AFAIK, I am trying to follow clang-tidy recommendation (without suppressing the warning)


Solution

  • Clang-tidy is correct from its point of view.

    The problem arises from the behavior of the API.

    According to the MPI_Comm_get_attr ducumentation, this is the signature of the function:

    int MPI_Comm_get_attr(MPI_Comm comm, int comm_keyval, void *attribute_val, int *flag)

    The 3rd parameter is a void*, not a void**, so Clang-tidy rightfully detected that a multi-level conversion is needed.

    However the MPI_Comm_get_attr ducumentation also states that:

    Even though the attr_value argument is declared as void *, it is really the address of a void pointer. See the rationale in the standard for more details.

    So you were right to pass &v as an argument.

    The only solution I see is to suppress Clang-tidy for this part of the code.