[cfe-commits] [PATCH] Fixing include order for Windows
Aaron Ballman
aaron at aaronballman.com
Sun Feb 19 17:35:51 PST 2012
On Sun, Feb 19, 2012 at 5:18 PM, Chandler Carruth <chandlerc at google.com> wrote:
> On Sun, Feb 19, 2012 at 3:09 PM, Aaron Ballman <aaron at aaronballman.com>
> wrote:
>>
>> On Sun, Feb 19, 2012 at 4:45 PM, Eli Friedman <eli.friedman at gmail.com>
>> wrote:
>> > On Sun, Feb 19, 2012 at 10:28 AM, Aaron Ballman <aaron at aaronballman.com>
>> > wrote:
>> >> On Windows, the default search paths for includes would put the
>> >> CMake-found headers (<build dir>\lib\clang\3.1\include) before the OS
>> >> headers. For the most part, this is fine. However, there are some
>> >> header files that share names with the system headers, which are
>> >> incorrect. For instance, immintrin.h is completely different from the
>> >> SDK include. This causes miscompilations in surprising places because
>> >> a system header will attempt to include one of these duplicates, and
>> >> find the clang header instead of the other system header.
>> >>
>> >> A simple test case of: #include <map> when building from MSVC
>> >> demonstrates the issue.
>> >>
>> >> A user can work around this behavior by specifying -nobuiltininc on
>> >> the command line, but that seems rather obtuse for such normal use
>> >> cases.
>> >>
>> >> I've fixed this by changing the order that the headers are included
>> >> from the toolchain. The SDK headers get added *before* the clang
>> >> headers, and this resolves the issue.
>> >>
>> >> This patch does cause one regression test to fail
>> >> (Modules\compiler_builtins.m). This is because the platform SDK
>> >> intrinsics are differently structured from the ones that come with
>> >> clang. The OS APIs expect the SDK intrinsics, but our tests seem to
>> >> require our own intrinsics. I'm open to suggestions.
>> >
>> > If on Windows, we specifically need the OS version of immintrin.h, we
>> > should modify our version to forward to it; completely ignoring the
>> > builtin headers is a bad idea (for example,
>> > http://llvm.org/bugs/show_bug.cgi?id=11918 is a miscompile caused by
>> > pulling in the wrong version of stdarg.h).
>>
>> The patch doesn't completely ignore the builtin headers though -- it
>> simply prefers the OS headers over the builtin headers.
>
>
> That doesn't work in the general case though -- look at all the places in
> our builtin headers where we specifically forward *to* the system headers.
> If the builtin doesn't come first, lots of things go wrong here.
>
> We should make our builtins always come first, and always be correct when
> they come first.
>
>> That being
>> said, I am not against forwarding our version. What would be a good
>> approach to it?
>
>
> Look at the other builtin headers that use '__has_include_next' and
> 'include_next' to fold together a Clang builtin header and a system builtin
> header.
>
> I suspect you will have to essentially tack on the system 'immintrin.h'
> header to the end of the builtin, as we do expect #include <immintrin.h> to
> pull in the Clang builtin bits... Essentially, this doesn't seem like it
> should be either-or, it should be both.
So how should I handle the duplicate declarations? For instance:
// mmintrin.h from MSVC
typedef union __declspec(intrin_type) _CRT_ALIGN(8) __m64
{
unsigned __int64 m64_u64;
float m64_f32[2];
__int8 m64_i8[8];
__int16 m64_i16[4];
__int32 m64_i32[2];
__int64 m64_i64;
unsigned __int8 m64_u8[8];
unsigned __int16 m64_u16[4];
unsigned __int32 m64_u32[2];
} __m64;
void _m_empty(void);
#define _mm_empty _m_empty
// mmintrin.h from clang
typedef long long __m64 __attribute__((__vector_size__(8)));
static __inline__ void __attribute__((__always_inline__, __nodebug__))
_mm_empty(void)
{
__builtin_ia32_emms();
}
#define _m_empty _mm_empty
It seems to me that trying to keep *both* headers is going to be
rather challenging given that both make the same typedefs in
incompatible ways, the declarations/macros are opposite one another,
etc.
~Aaron
More information about the cfe-commits
mailing list