Skip to content

#include_next fails with -idirafter in compile_commands.json on Clang 22+ #4781

@gamesh411

Description

@gamesh411

#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:

  1. <cstdlib> is found via -idirafter /path/to/c++/13.4.0
  2. Inside <cstdlib>, #include_next <stdlib.h> searches for the next stdlib.h
  3. Since all paths use -idirafter (lowest priority), there is no "next" location to search
  4. 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions