llvm / llvm-project

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

Bogus non-portable path warnings #31783

Open llvmbot opened 7 years ago

llvmbot commented 7 years ago
Bugzilla Link 32436
Version 9.0
OS Linux
Reporter LLVM Bugzilla Contributor
CC @adzenith,@rnk

Extended Description

Clang 4.0 reports bogus warnings about non-portable paths on Linux (where non-portable paths probably can't even exist).

Example: /home/lubos/Projects/darling/src/external/corefoundation/CoreFoundation/CFRunLoop.h:33:10: warning: non-portable path to file '<corefoundation/CFDate.h>'; specified path differs in case from file name on disk [-Wnonportable-include-path]

include <CoreFoundation/CFDate.h>

     ^~~~~~~~~~~~~~~~~~~~~~~~~
     <corefoundation/CFDate.h>

This happens when building source code on Linux with '-target x86_64-apple-darwin11' (crosscompiling).

As is obvious from the example above, it seems clang internally makes parts of the include path lower case, only to later complain about it.

adzenith commented 4 years ago

I just ran into this same issue in Clang 9. It looks like this warning will fire any time that the path of the symlink's target is the same (except for case) as the include path. Another repro without folders at all:

touch foo.h ln -s foo.h Foo.h echo '#include "Foo.h"' | clang -c -xc -

Output:

:1:10: warning: non-portable path to file '"foo.h"'; specified path differs in case from file name on disk [-Wnonportable-include-path] #include "Foo.h" ^~~~~~~ "foo.h" 1 warning generated. It looks like source for this warning is somewhere in here: https://github.com/llvm-mirror/clang/blob/c6e4e7210cd1f80a0492f6bf1dc1f717a1cf0351/lib/Lex/PPDirectives.cpp#L2096.
llvmbot commented 7 years ago

I don't know if this scenario is the only one that causes the problem, but I wonder how it makes the check?

I'm not directly using the lower-case path anywhere in my example and if it would check the path directory-by-directory, it would see it's perfectly correct.

llvmbot commented 7 years ago

Is it only a problem if you have created a symbolic link to the same directory with the same name only differing in case?

If we knew the file in question lives on a case-sensitive file system, we could just not issue the warning. Not sure if we can get that information, though.

llvmbot commented 7 years ago

Oops, sorry my bad. Thanks!

llvmbot commented 7 years ago

It's -I./testdir, not -I../testdir

llvmbot commented 7 years ago

Thank you for the report. I cced Eric, who is the original author of this code.

I tried repro on my linux machine with more recent clang (about 2 weeks old), but it throws a file not found error:

echo "#include <TestDir/header.h>" | ~/llvms/fb-master/install-release/bin/clang -c -xc -I. -I../testdir -

:1:10: fatal error: 'TestDir/header.h' file not found #include ^~~~~~~~~~~~~~~~~~ 1 error generated. Did I miss anything? Thanks!
rnk commented 7 years ago

Got it. This seems like a bad false positive, since testdir/header.h doesn't actually exist, and #include <testdir/header.h> would fail.

Thanks for the test case. Hopefully Taewook has some time to look into it.

llvmbot commented 7 years ago

I've figured it out, it's a little more complicated. Clang seems to check if the included file is also available when a different case is used for parts of the path. If that happens to be the case, it reports a warning.

Reproducer:

mkdir testdir touch testdir/header.h ln -s . testdir/TestDir echo "#include <TestDir/header.h>" | clang-4.0 -c -xc -I. -I./testdir -

Will produce this output:

:1:10: warning: non-portable path to file ''; specified path differs in case from file name on disk [-Wnonportable-include-path] #include ^~~~~~~~~~~~~~~~~~ 1 warning generated.
rnk commented 7 years ago

Can you provide a reproducer? I suspect this is some bad interaction between frameworks / modules / stuff that Apple uses and -Wnonportable-include-path, which probably assumes normal include path search.