#include_next fails with -idirafter in compile_commands.json on Clang 22+
Summary
When compile_commands.json contains -idirafter flags for C++ standard library headers (common in cross-compilation setups), analysis fails with Clang 22+ due to #include_next not finding system headers. The --add-gcc-include-dirs-with-isystem flag only transforms compiler includes extracted by CodeChecker, not the flags already present in the build command.
Environment
- CodeChecker version: 6.27.1
- Clang version: 22.0.0git
- Build system: Cross-compilation with sysroot (Wind River Linux SDK)
Root Cause
The C++ standard library header <cstdlib> uses #include_next <stdlib.h> to include the C library header. This directive searches for the next occurrence of the header in the include path after the current directory. When all headers are added with -idirafter, they are searched last, breaking the #include_next chain.
This is a known Clang issue in cross-compilation scenarios:
- LLVM Issue #63537: "
#include_next broken in sysroot environments"
- LLVM Issue #114210: Related cross-compilation issue
Steps to Reproduce
compile_commands.json:
[
{
"directory": "/path/to/project",
"command": "clang++ -c --sysroot=/path/to/sysroot -std=c++17 -idirafter /path/to/sysroot/usr/include/c++/13.4.0 -idirafter /path/to/sysroot/usr/include/c++/13.4.0/x86_64-wrs-linux -idirafter /path/to/sysroot/usr/include/c++/13.4.0/backward -idirafter /path/to/sysroot/usr/include test.cpp",
"file": "test.cpp"
}
]
test.cpp:
#include <string>
int main() {
std::string s = "test";
return 0;
}
Command:
CodeChecker analyze compile_commands.json -o reports --analyzers clangsa
Expected Behavior
Analysis should succeed, or the --add-gcc-include-dirs-with-isystem flag should transform -idirafter to -isystem in the build command.
Actual Behavior
Analysis fails with:
fatal error: 'stdlib.h' file not found
79 | #include_next <stdlib.h>
| ^~~~~~~~~~
The --add-gcc-include-dirs-with-isystem flag only affects compiler includes extracted by CodeChecker, not the -idirafter flags already in the compile command.
Impact
- Cannot analyze cross-compiled code with Clang 22+ when build system uses
-idirafter
- Affects Wind River Linux SDK and similar cross-compilation toolchains
- Workaround requires manually editing compile_commands.json
Technical Details
The issue occurs because:
<cstdlib> is found via -idirafter /path/to/c++/13.4.0
- Inside
<cstdlib>, #include_next <stdlib.h> searches for the next stdlib.h
- Since all paths use
-idirafter (lowest priority), there is no "next" location to search
- Clang 22+ is stricter about this than Clang 18
Proposed Solution
Extend --add-gcc-include-dirs-with-isystem to also transform -idirafter flags from the original build command to -isystem, not just the compiler includes extracted by CodeChecker.
Related
- Commit e1d2907: Introduced
-idirafter for compiler includes
- LLVM #63537:
#include_next broken in sysroot
- LLVM #114210: Cross-compilation issue
#include_nextfails with-idirafterin compile_commands.json on Clang 22+Summary
When
compile_commands.jsoncontains-idirafterflags for C++ standard library headers (common in cross-compilation setups), analysis fails with Clang 22+ due to#include_nextnot finding system headers. The--add-gcc-include-dirs-with-isystemflag only transforms compiler includes extracted by CodeChecker, not the flags already present in the build command.Environment
Root Cause
The C++ standard library header
<cstdlib>uses#include_next <stdlib.h>to include the C library header. This directive searches for the next occurrence of the header in the include path after the current directory. When all headers are added with-idirafter, they are searched last, breaking the#include_nextchain.This is a known Clang issue in cross-compilation scenarios:
#include_nextbroken in sysroot environments"Steps to Reproduce
compile_commands.json:
[ { "directory": "/path/to/project", "command": "clang++ -c --sysroot=/path/to/sysroot -std=c++17 -idirafter /path/to/sysroot/usr/include/c++/13.4.0 -idirafter /path/to/sysroot/usr/include/c++/13.4.0/x86_64-wrs-linux -idirafter /path/to/sysroot/usr/include/c++/13.4.0/backward -idirafter /path/to/sysroot/usr/include test.cpp", "file": "test.cpp" } ]test.cpp:
Command:
Expected Behavior
Analysis should succeed, or the
--add-gcc-include-dirs-with-isystemflag should transform-idirafterto-isystemin the build command.Actual Behavior
Analysis fails with:
The
--add-gcc-include-dirs-with-isystemflag only affects compiler includes extracted by CodeChecker, not the-idirafterflags already in the compile command.Impact
-idirafterTechnical Details
The issue occurs because:
<cstdlib>is found via-idirafter /path/to/c++/13.4.0<cstdlib>,#include_next <stdlib.h>searches for the nextstdlib.h-idirafter(lowest priority), there is no "next" location to searchProposed Solution
Extend
--add-gcc-include-dirs-with-isystemto also transform-idirafterflags from the original build command to-isystem, not just the compiler includes extracted by CodeChecker.Related
-idirafterfor compiler includes#include_nextbroken in sysroot