5

In the following C program, functions f, g, and h are essentially identical, however clang-tidy says that parameter p can be pointer-to-const in g and h (but not in f). My understanding is that p can't be pointer-to-const in any of them. Is that a false positive?

struct S { int *p; };

extern void x(struct S *s);

void f(int *p)
{
    struct S s;
    s.p = p;
    x(&s);
}

void g(int *p)
{
    struct S s = { .p = p };
    x(&s);
}

void h(int *p)
{
    struct S s = { p };
    x(&s);
}

int main()
{
    int a = 0;
    f(&a);
    g(&a);
    h(&a);
}

Output from clang-tidy:

$ clang-tidy --checks=* a.c
Error while trying to load a compilation database:
Could not auto-detect compilation database for file "a.c"
No compilation database found in /home/wolfram or any parent directory
fixed-compilation-database: Error while opening fixed database: No such file or directory
json-compilation-database: Error while opening JSON database: No such file or directory
Running without flags.
2 warnings generated.
/home/wolfram/a.c:14:13: warning: pointer parameter 'p' can be pointer to const [readability-non-const-parameter]
void g(int *p)
            ^
       const 
/home/wolfram/a.c:20:13: warning: pointer parameter 'p' can be pointer to const [readability-non-const-parameter]
void h(int *p)
            ^
       const 

Tried with clang-tidy versions 10 and 11.

The following may be related: https://bugs.llvm.org/show_bug.cgi?id=41393

Wolfram Rösler
  • 302
  • 1
  • 12
  • What happens if you change the order of the calls to `f`, `g` and `h`? Or give different arguments (i.e. addresses of different integers) to each call? – Adrian Mole Nov 19 '20 at 09:35
  • @AdrianMole that changes nothing. I can even remove the main function altogether, the result is the same. – Wolfram Rösler Nov 19 '20 at 09:39
  • 1
    Definitely looks like clang-tidy bug. This parameter cannot be a pointer to const, in neither of the functions. Try it, change it to pointer to const - you will probably get another warning, on assignment discarding const qualifier. – Yuri Nudelman Nov 19 '20 at 09:43
  • 2
    The bug you referenced looks like exactly that issue - it probably has some trouble parsing struct initializes. Seems you answered your own question. – Yuri Nudelman Nov 19 '20 at 09:46
  • Reported as a clang-tidy bug to the LLVM Bugzilla: https://bugs.llvm.org/show_bug.cgi?id=48243 – Wolfram Rösler Nov 20 '20 at 15:09

1 Answers1

1

The tool is bugged. The intention of this warning is to likely to enforce "const-correctness", something that only matters when the pointer is actually de-referenced inside the function. You don't de-reference the pointers.

But more importantly, the C language requires this for simple assignment of pointers (6.5.1.6.1), emphasis mine:

  • the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;

Making the pointer parameter const would turn s.p = p; and similar into constraint violations - invalid C. The rules of initialization follow the rules of simple assignment too, so the various functions behave identically.

Lundin
  • 195,001
  • 40
  • 254
  • 396