llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.98k stars 11.55k forks source link

clang-modernize checks wrong directory for includes #19501

Closed Trass3r closed 8 years ago

Trass3r commented 10 years ago
Bugzilla Link 19127
Resolution WONTFIX
Resolved on Sep 28, 2015 07:46
Version unspecified
OS All
Attachments test files

Extended Description

I have a compilation database for a set of libraries and applications (with relative include paths). It seems like clang-modernize is doing multiple files in parallel and mixes up the working directories or something like that which leads to complaints about non-existing header files. I verified with strace that it actually checks the correct -I../.... path but it is not existing which makes me think it's in the wrong folder.

I tried to reduce it and came up with the attached sample. When renaming the main.cpp in app to foo.cpp and adapting the db it strangely works but as is it triggers an assertion. I hope this points to the root cause.

$ strace -e trace=open,stat,fstat clang-modernize -debug -summary -add-override -p . -include .

open("/opt/clang/bin/../lib/tls/x86_64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/opt/clang/bin/../lib/tls/x86_64", 0x7fff7f59d610) = -1 ENOENT (No such file or directory) open("/opt/clang/bin/../lib/tls/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/opt/clang/bin/../lib/tls", 0x7fff7f59d610) = -1 ENOENT (No such file or directory) open("/opt/clang/bin/../lib/x86_64/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/opt/clang/bin/../lib/x86_64", 0x7fff7f59d610) = -1 ENOENT (No such file or directory) open("/opt/clang/bin/../lib/libpthread.so.0", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) stat("/opt/clang/bin/../lib", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=109868, ...}) = 0 open("/lib/x86_64-linux-gnu/libpthread.so.0", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0755, st_size=141574, ...}) = 0 open("/opt/clang/bin/../lib/libdl.so.2", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libdl.so.2", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=14664, ...}) = 0 open("/opt/clang/bin/../lib/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/usr/lib/x86_64-linux-gnu/libstdc++.so.6", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=979056, ...}) = 0 open("/opt/clang/bin/../lib/libm.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libm.so.6", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=1071552, ...}) = 0 open("/opt/clang/bin/../lib/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libgcc_s.so.1", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=90696, ...}) = 0 open("/opt/clang/bin/../lib/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/lib/x86_64-linux-gnu/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 fstat(3, {st_mode=S_IFREG|0755, st_size=1845024, ...}) = 0 Args: clang-modernize -debug -summary -add-override -p . -include . stat("/tmp/src", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 stat(".", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 Parse: /tmp/src stat("/tmp/src", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 stat(".", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 open("/tmp/src/./compile_commands.json", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0664, st_size=242, ...}) = 0 stat("/opt/clang/bin/clang-apply-replacements", {st_mode=S_IFREG|0755, st_size=1586416, ...}) = 0 open("/dev/urandom", O_RDONLY) = 3 fstat(3, {st_mode=S_IFCHR|0666, st_rdev=makedev(1, 9), ...}) = 0 Processing: /tmp/src/apps2/main.cpp. stat("/usr/bin/ld", {st_mode=S_IFREG|0755, st_size=1050904, ...}) = 0 open("/etc/lsb-release", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=126, ...}) = 0 stat("/tmp/src", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 stat(".", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 stat("../libs", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 stat("/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0 stat("/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/x86_64-linux-gnu", 0x7fff7f59c010) = -1 ENOENT (No such file or directory) stat("/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/x86_64-linux-gnu", 0x7fff7f59c000) = -1 ENOENT (No such file or directory) stat("/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 stat("/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 stat("/usr/local/include", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 stat("/opt/clang/bin/../lib/clang/3.5.0/include", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 stat("/usr/include/x86_64-linux-gnu", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 stat("/include", 0x7fff7f59c010) = -1 ENOENT (No such file or directory) stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 stat("/include", 0x7fff7f59c000) = -1 ENOENT (No such file or directory) stat("/usr/include", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0 open("/System/Library/CoreServices/SystemVersion.plist", O_RDONLY) = -1 ENOENT (No such file or directory) stat(".", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 open("main.cpp", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0664, st_size=19, ...}) = 0 open("./test.h", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0 Processing: /tmp/src/apps/main.cpp. stat("/usr/bin/ld", {st_mode=S_IFREG|0755, st_size=1050904, ...}) = 0 open("/etc/lsb-release", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0644, st_size=126, ...}) = 0 stat("/tmp/src", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 stat(".", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 open("/System/Library/CoreServices/SystemVersion.plist", O_RDONLY) = -1 ENOENT (No such file or directory) open("main.cpp", O_RDONLY) = 3 clang-modernize: llvm/lib/Support/MemoryBuffer.cpp:416: llvm::error_code getOpenFileImpl(int, const char*, std::unique_ptr&, uint64_t, uint64_t, int64_t, bool): Assertion `0 && "We got inaccurate FileSize value or fstat reported an " "invalid file size."' failed. --- SIGABRT {si_signo=SIGABRT, si_code=SI_TKILL, si_pid=32322, si_uid=1000} ---

llvmbot commented 8 years ago

clang-modernize is going away soon. All transforms have been migrated to clang-tidy (http://clang.llvm.org/extra/clang-tidy/). If the issue is still relevant, please file a separate bug with reproduction instructions. Thanks!

Trass3r commented 10 years ago

Even when replacing all include paths in my real-world code with absolute paths the preprocessor handling is a mess. This renders clang-modernize totally unusable for me.

Trass3r commented 10 years ago

On Windows the situation is a bit different.

{ "directory": "D:/test/clangmodernize/libs/a/test", "command": "clang++ -c -v -I../../../libs t.cpp", "file": "D:/test/clangmodernize/libs/a/test/t.cpp" }

"command": "clang++ -c -v -I..\..\..\libs t.cpp" "command": 'clang++ -c -v -I......\libs t.cpp' equivalent, parsed as "......\libs", see JSONCompilationDatabase::getCommands => unescapeCommandLine.

"command": "clang++ -c -v -I../../../libs t.cpp" "command": 'clang++ -c -v -I..\..\..\libs t.cpp' fix that problem but it still doesn't work cause of mixed slashes (but surprisingly unlike on Linux the path is correct otherwise, 3 levels up):

include <...> search starts here:

......\libs (resp. ../../../libs) D:\tools\llvm\objdir\Debug\bin..\lib\clang\3.5.0\include C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\include C:\Program Files (x86)\Windows Kits\8.1\include End of search list. Processing: D:\test\clangmodernize\libs\a\a.cpp. a.cpp:2:10: fatal error: cannot open file '......\libs\a/a.h' (resp. '../../../libs\a/a.h'): The system cannot find the path specified

include "a.h"

     ^

1 error generated. Error while processing D:\test\clangmodernize\libs\a\a.cpp.

Also note that clang itself doesn't have that problem (similar to the situation on Linux).

Trass3r commented 10 years ago

proper test files Seems like the problem with the previous test set isn't present anymore. Here's a new one. It correctly checks 'stat("../../../libs,..) = 0"' but right afterwards searches 'stat("../../libs/a",..) = -1'

$ strace -e trace=open,stat,fstat,chdir clang-modernize -debug -summary -add-override -p . -include . stat("/tmp/src", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 stat(".", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 Parse: /tmp/src stat("/tmp/src", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 stat(".", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 open("/tmp/src/./compile_commands.json", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0664, st_size=255, ...}) = 0 chdir("/tmp/src/libs/a") = 0 Processing: /tmp/src/libs/a/a.cpp. stat("/tmp/src", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 stat(".", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 stat("../../libs", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 stat("/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0 stat("/usr/local/include", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 stat("/opt/clang/bin/../lib/clang/3.5.0/include", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 stat("/include", 0x7fff11006b88) = -1 ENOENT (No such file or directory) stat("/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 stat("/include", 0x7fff11006b78) = -1 ENOENT (No such file or directory) stat("/usr/include", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0 stat(".", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 open("a.cpp", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0664, st_size=16, ...}) = 0 open("./a.h", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0664, st_size=16, ...}) = 0 open("./b.h", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0664, st_size=0, ...}) = 0 chdir("/tmp/src/libs/a/test") = 0 Processing: /tmp/src/libs/a/test/t.cpp. stat("/tmp/src", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 stat(".", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 stat("../../../libs", {st_mode=S_IFDIR|0775, st_size=4096, ...}) = 0 open("t.cpp", O_RDONLY) = 3 fstat(3, {st_mode=S_IFREG|0664, st_size=18, ...}) = 0 stat("../../libs/a", 0x7fff11006148) = -1 ENOENT (No such file or directory) stat("/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/a", 0x7fff11006148) = -1 ENOENT (No such file or directory) stat("/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/c++/4.8/backward/a", 0x7fff11006148) = -1 ENOENT (No such file or directory) stat("/usr/lib/gcc/x86_64-linux-gnu/4.8/../../../../include/x86_64-linux-gnu/c++/4.8/a", 0x7fff11006148) = -1 ENOENT (No such file or directory) stat("/usr/local/include/a", 0x7fff11006148) = -1 ENOENT (No such file or directory) stat("/opt/clang/bin/../lib/clang/3.5.0/include/a", 0x7fff11006148) = -1 ENOENT (No such file or directory) stat("/usr/include/x86_64-linux-gnu/a", 0x7fff11006148) = -1 ENOENT (No such file or directory) stat("/usr/include/a", 0x7fff11006148) = -1 ENOENT (No such file or directory) stat("./a", 0x7fff11006a68) = -1 ENOENT (No such file or directory) t.cpp:2:10: fatal error: 'a/a.h' file not found

include <a/a.h>

     ^

1 error generated. Error while processing /tmp/src/libs/a/test/t.cpp. Error encountered during translation.

Trass3r commented 10 years ago

No seems like it's in the right working dir after all. It only does 1 chdir right before each "Processing ..." printout. But still it tries to open a header #include "" 'd in another directory in the current one.