<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </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 --- - Possible defect in implementation of clang compiler headers, vis-a-vis include_next"
   href="https://llvm.org/bugs/show_bug.cgi?id=24754">24754</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>Possible defect in implementation of clang compiler headers, vis-a-vis include_next
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>new-bugs
          </td>
        </tr>

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

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>MacOS X
          </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>unassignedbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>nikkoara@hates.ms
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>My platform is Mac OSX, stock clang. Taking the case of the header stdint.h:

$ cat t.cpp
#include <stdint.h>

int main () {
    return uint8_t ();
}

Notice the way the compiler internal stdint.h header includes the system
stdint.h which, in turn, includes the other relevant headers:

$ clang -E t.cpp
# 1 "t.cpp"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 326 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "t.cpp" 2
# 1
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.1.0/include/stdint.h"
1 3 4
# 63
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.1.0/include/stdint.h"
3 4
# 1 "/usr/include/stdint.h" 1 3 4
# 18 "/usr/include/stdint.h" 3 4
# 1 "/usr/include/sys/_types/_int8_t.h" 1 3 4
# 30 "/usr/include/sys/_types/_int8_t.h" 3 4
typedef __signed char int8_t;
[...]
$

This is accomplished through the following steps:

1. First include finds and includes the compiler internal as a system include
2. That header include_next the same header, search finds system header

However, including directly the compiler header:

$ cat t.cpp
#include
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.1.0/include/stdint.h"

int main () {
    return uint8_t ();
}

does not result in the inclusion of the system header and the compilation
fails:

$ clang -c -v t.cpp
Apple LLVM version 6.1.0 (clang-602.0.53) (based on LLVM 3.6.0svn)
Target: x86_64-apple-darwin14.5.0
Thread model: posix

"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang"
[...] -o t.o -x c++ t.cpp
clang -cc1 version 6.1.0 based upon LLVM 3.6.0svn default target
x86_64-apple-darwin14.5.0
ignoring nonexistent directory "/usr/include/c++/v1"
ignoring nonexistent directory "/usr/local/include"
#include "..." search starts here:
#include <...> search starts here:

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.1.0/include

/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include
 /usr/include
 /System/Library/Frameworks (framework directory)
 /Library/Frameworks (framework directory)
End of search list.
In file included from t.cpp:1:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.1.0/include/stdint.h:31:24:
warning:
[...]
t.cpp:4:12: error: use of undeclared identifier 'uint8_t'
    return uint8_t ();
           ^
2 warnings and 1 error generated.

Notice how the compiler header includes itself, recursively, via the
include_next at line 63:

$ clang -E t.cpp
# 1 "t.cpp"
# 1 "<built-in>" 1
# 1 "<built-in>" 3
# 326 "<built-in>" 3
# 1 "<command line>" 1
# 1 "<built-in>" 2
# 1 "t.cpp" 2
# 1
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.1.0/include/stdint.h"
1
In file included from t.cpp:1:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.1.0/include/stdint.h:31:24:
warning:
      #include_next with absolute path
#if __STDC_HOSTED__ && __has_include_next(<stdint.h>)
                       ^
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.1.0/include/stdint.h:63:3:
warning:
      #include_next with absolute path
# include_next <stdint.h>
  ^
# 63
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.1.0/include/stdint.h"
# 1
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.1.0/include/stdint.h"
1 3 4
# 64
"/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../lib/clang/6.1.0/include/stdint.h"
2
# 2 "t.cpp" 2

int main () {
    return uint8_t ();
}
2 warnings generated.

Here is the thing.

The compiler stdint.h is guarded in a classical manner, which prevents
recursive includes. This prevents the including of the system header when the
compiler header is included directly. Such a direct inclusion would be used,
e.g., by an alternative implementation of the C++ Standard Library. Regardless,
the direct inclusion of the compiler header should not result in a different
behavior.

Contrast this implementation of stdint.h with the GNU Linux/GCC stdint.h, for
the same headers:

$ cat t.cpp
#include "/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h"

int main () {
    return uint8_t ();
}

$ gcc -E t.cpp
# 1 "t.cpp"
# 1 "<built-in>"
# 1 "<command-line>"
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "<command-line>" 2
# 1 "t.cpp"
# 1 "/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h" 1
# 9 "/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h"
# 1 "/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h" 1 3 4
# 9 "/usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h" 3 4
# 1 "/usr/include/stdint.h" 1 3 4
# 25 "/usr/include/stdint.h" 3 4
[...]
$

Notice the recursive include above. The structure of the compiler internal is:

$ cat /usr/lib/gcc/x86_64-linux-gnu/4.8/include/stdint.h
#ifndef _GCC_WRAP_STDINT_H
#if __STDC_HOSTED__
# if defined __cplusplus && __cplusplus >= 201103L
#  undef __STDC_LIMIT_MACROS
#  define __STDC_LIMIT_MACROS
#  undef __STDC_CONSTANT_MACROS
#  define __STDC_CONSTANT_MACROS
# endif
# include_next <stdint.h>
#else
# include "stdint-gcc.h"
#endif
#define _GCC_WRAP_STDINT_H
#endif

Notice the different guarding which does not prevent a recursive include in the
scenario detailed above. It seems that the gcc header implementation explicitly
addresses this situation.</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>