<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - Empty components in CPATH and friends handled inconsistently"
   href="https://bugs.llvm.org/show_bug.cgi?id=50398">50398</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Empty components in CPATH and friends handled inconsistently
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>unspecified
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>-New Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>dg0yt@darc.de
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>htmldeveloper@gmail.com, llvm-bugs@lists.llvm.org, neeilans@live.com, richard-llvm@metafoo.co.uk
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Originally discovered with Apple's toolchain on macOS:

clang documentation for CPATH, C_INCLUDE_PATH and friends says that "Empty
components in the environment variable are ignored." 
<a href="https://clang.llvm.org/docs/CommandGuide/clang.html#envvar-C_INCLUDE_PATH,OBJC_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJCPLUS_INCLUDE_PATH">https://clang.llvm.org/docs/CommandGuide/clang.html#envvar-C_INCLUDE_PATH,OBJC_INCLUDE_PATH,CPLUS_INCLUDE_PATH,OBJCPLUS_INCLUDE_PATH</a>

But this is not true, as can be verified by experimentation and source code
inspection.

- Empty components at the beginning or end are treated as "."
 
<a href="https://github.com/llvm/llvm-project/blob/5f58322368b070b63fe2b2559a54f646cb97e2c4/clang/lib/Driver/ToolChains/CommonArgs.cpp#L187-L221">https://github.com/llvm/llvm-project/blob/5f58322368b070b63fe2b2559a54f646cb97e2c4/clang/lib/Driver/ToolChains/CommonArgs.cpp#L187-L221</a> 
  This is as documented for gcc: 
 
<a href="https://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html#index-environment-variables">https://gcc.gnu.org/onlinedocs/cpp/Environment-Variables.html#index-environment-variables</a>

- Unlike CPATH (`-I`), the components in the per-language variables are added
as *system include directories* (`-c-isystem`).
 
<a href="https://github.com/llvm/llvm-project/blob/6381664580080f015bc0c2ec647853f697cf744a/clang/lib/Driver/ToolChains/Clang.cpp#L1389-L1392">https://github.com/llvm/llvm-project/blob/6381664580080f015bc0c2ec647853f697cf744a/clang/lib/Driver/ToolChains/Clang.cpp#L1389-L1392</a>

- For system include directories, clang removes the earlier duplicates, i.e.
those from command line arguments.
 
<a href="https://github.com/llvm/llvm-project/blob/d480f968ad8b56d3ee4a6b6df5532d485b0ad01e/clang/lib/Frontend/InitHeaderSearch.cpp#L496-L503">https://github.com/llvm/llvm-project/blob/d480f968ad8b56d3ee4a6b6df5532d485b0ad01e/clang/lib/Frontend/InitHeaderSearch.cpp#L496-L503</a>

Reproducer:

~~~sh
mkdir /tmp/MARK-I-OPTION
mkdir /tmp/MARK-ENV-VAR
echo | C_INCLUDE_PATH=/tmp/MARK-ENV-VAR clang -E -Wp,-v - -o /dev/null -I.
-I/tmp/MARK-I-OPTION 2> c_include_path-no-colon 
echo | C_INCLUDE_PATH=/tmp/MARK-ENV-VAR: clang -E -Wp,-v - -o /dev/null -I.
-I/tmp/MARK-I-OPTION 2> c_include_path-with-colon
diff -U20 c_include_path-no-colon c_include_path-with-colon
echo | CPATH=/tmp/MARK-ENV-VAR clang -E -Wp,-v - -o /dev/null -I.
-I/tmp/MARK-I-OPTION 2> cpath-no-colon 
echo | CPATH=/tmp/MARK-ENV-VAR: clang -E -Wp,-v - -o /dev/null -I.
-I/tmp/MARK-I-OPTION 2> cpath-with-colon 
diff -U20 cpath-no-colon cpath-with-colon
~~~

Output for C_INCLUDE_PATH (somewhat older clang on Linux):

~~~diff
--- c_include_path-no-colon     2021-05-18 19:23:22.718867910 +0200
+++ c_include_path-with-colon   2021-05-18 19:59:06.197846524 +0200
@@ -1,12 +1,14 @@
 clang -cc1 version 8.0.0 based upon LLVM 8.0.0 default target
x86_64-pc-linux-gnu
 ignoring nonexistent directory "/include"
+ignoring duplicate directory "."
+  as it is a non-system directory that duplicates a system directory
 #include "..." search starts here:
 #include <...> search starts here:
- .
  /tmp/MARK-I-OPTION
  /tmp/MARK-ENV-VAR
+ .
  /usr/local/include
  /usr/lib/llvm-8/lib/clang/8.0.0/include
  /usr/include/x86_64-linux-gnu
  /usr/include
 End of search list.
~~~

Output for CPATH:

~~~diff
--- cpath-no-colon      2021-05-18 19:23:53.654933769 +0200
+++ cpath-with-colon    2021-05-18 19:24:00.914949225 +0200
@@ -1,12 +1,13 @@
 clang -cc1 version 8.0.0 based upon LLVM 8.0.0 default target
x86_64-pc-linux-gnu
 ignoring nonexistent directory "/include"
+ignoring duplicate directory "."
 #include "..." search starts here:
 #include <...> search starts here:
  .
  /tmp/MARK-I-OPTION
  /tmp/MARK-ENV-VAR
  /usr/local/include
  /usr/lib/llvm-8/lib/clang/8.0.0/include
  /usr/include/x86_64-linux-gnu
  /usr/include
~~~

In particular, the behaviour for per-language variables is a subtle source of
errors when includes which are expected to be found from the current directory
happen to be found in other directories.
E.g. for building gettext tools with vcpkg on osx,
<a href="https://github.com/microsoft/vcpkg/pull/17970#issuecomment-842502062">https://github.com/microsoft/vcpkg/pull/17970#issuecomment-842502062</a>


Expected behaviour:
- Consistent with documentation
- No removal of user-specified early "."</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>