cvisual-studio-codearmclang-tidy

stddef.h redefines size_t with the wrong width only in clang-tidy


I have two parallel build stacks. In the first (working) stack, GCC 7.3.1-1.2.2 installed as a cross-compiler is building for a 32-bit Arm target.

In the second (broken) stack, vscode 1.90.1 with the C/C++ plugin 1.20.5 has clang-tidy enabled. Clang has been told where the true compiler lives via c_cpp_properties.json compilerPath. I tried to lint the code via clang-tidy. I know it compiles "in real life", but clang-tidy is full of false positives. I've also run

echo | /.../arm-none-eabi-gcc/7.3.1-1.2.2/.content/bin/arm-none-eabi-g++.exe (realistic-args...) -dM -E -x c++ -

to extract realistic defines; some relevant ones that I've set in the defines configuration are

                "__GNUG__=7",
                "__SIZE_MAX__=0xffffffffU",
                "__SIZE_TYPE__=unsigned int",
                "__SIZE_WIDTH__=32",
                "__SIZEOF_SIZE_T__=4",

which all appear correct. And, even, in a blank .cpp when I write

unsigned int z = sizeof(int);

there are no inspection errors and mousing over the sizeof expression shows (unsigned int)4U, also as expected.

The problem comes when I include stddef.h directly or indirectly through basically any part of the STL. clang-tidy has a crisis, fails to parse the file, and writes

stddef.h[Ln 216, Col 23]: typedef redefinition with different types ('unsigned int' vs 'unsigned long long')

The region it's complaining about is

#if !(defined (__GNUG__) && defined (size_t))
typedef __SIZE_TYPE__ size_t;

There are endless cascading failures after that. The operator new signatures fail because of 32/64 mismatches, and <string> has similar failures because of template mismatches on size_t.

What gives? Where is size_t coming from that it would not trigger the #if's predicate, but would trigger the typedef to fail? This seems to be a bug in clang-tidy (and not vscode or gcc), because I tried clang-tidy on a trivial input file from the command line and it failed in a similar manner.

I tried adding

"compilerArgs": [
    "-isystem", "${env:APPDATA}/xPacks/@xpack-dev-tools/arm-none-eabi-gcc"
]

but this also did not help.

Related

clang-tidy false positive: stddef.h size_t - similar issue, but with a different toolchain (ESP-IDF, which I am not using); and the one answer of

"C_Cpp.intelliSenseEngine": "Tag Parser"

does not change anything for me.

Clang-tidy: how to configure size_t, uintptr_t and pointers to 32-bits?

turns out to have the correct solution, but for a question with different search terms and a different description.


Solution

  • Even though this answer - Clang-tidy: how to configure size_t, uintptr_t and pointers to 32-bits? - is to a question that is not Arm-specific, it is still exactly what I needed to do. Modify settings.json to include

    "C_Cpp.codeAnalysis.clangTidy.args": [
        "--extra-arg=--target=arm"
    ],
    

    and all of the 32/64 issues go away. Note that this is not the same as including --target=arm in compilerArgs.