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.
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.
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
.