[libcxx-commits] [libcxx] 8cedff1 - [libc++] Diagnose when header search paths are set up incorrectly

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Wed Aug 17 11:05:40 PDT 2022


Author: Louis Dionne
Date: 2022-08-17T14:05:26-04:00
New Revision: 8cedff10a18d8eba9190a645626fa6a509c1f139

URL: https://github.com/llvm/llvm-project/commit/8cedff10a18d8eba9190a645626fa6a509c1f139
DIFF: https://github.com/llvm/llvm-project/commit/8cedff10a18d8eba9190a645626fa6a509c1f139.diff

LOG: [libc++] Diagnose when header search paths are set up incorrectly

An issue I often see in codebases compiled for unusual platforms is
that header search paths are specified manually and are subtly wrong.
For example, people will manually add `-isystem <some-toolchain>/usr/include`,
which ends up messing up the layering of header search paths required by
libc++ (because the C Standard Library now appears *before* libc++ in
the search paths). Without this patch, this will end up causing
compilation errors that are pretty inscrutable. This patch aims to
improve the user experience by diagnosing this issue explicitly.

In all cases I can think of, I would expect that a compilation error
occur if these header search paths are not layered properly. This
should only provide an explicit diagnostic instead of failing due
to seemingly unrelated compilation errors.

Differential Revision: https://reviews.llvm.org/D131441

Added: 
    

Modified: 
    libcxx/include/cctype
    libcxx/include/cerrno
    libcxx/include/cfenv
    libcxx/include/cfloat
    libcxx/include/cinttypes
    libcxx/include/climits
    libcxx/include/clocale
    libcxx/include/cmath
    libcxx/include/csetjmp
    libcxx/include/cstddef
    libcxx/include/cstdint
    libcxx/include/cstdio
    libcxx/include/cstdlib
    libcxx/include/cstring
    libcxx/include/cuchar
    libcxx/include/cwchar
    libcxx/include/cwctype

Removed: 
    


################################################################################
diff  --git a/libcxx/include/cctype b/libcxx/include/cctype
index 248f8d98000f..867e7d5b0b35 100644
--- a/libcxx/include/cctype
+++ b/libcxx/include/cctype
@@ -36,8 +36,16 @@ int toupper(int c);
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+
 #include <ctype.h>
 
+#ifndef _LIBCPP_CTYPE_H
+#   error <cctype> tried including <ctype.h> but didn't find libc++'s <ctype.h> header. \
+          This usually means that your header search paths are not configured properly.  \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif

diff  --git a/libcxx/include/cerrno b/libcxx/include/cerrno
index e9eacd35effe..937ec23c6971 100644
--- a/libcxx/include/cerrno
+++ b/libcxx/include/cerrno
@@ -24,8 +24,17 @@ Macros:
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+
 #include <errno.h>
 
+#ifndef _LIBCPP_ERRNO_H
+#   error <cerrno> tried including <errno.h> but didn't find libc++'s <errno.h> header. \
+          This usually means that your header search paths are not configured properly. \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library, and you are probably using compiler flags that make that \
+          not be the case.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif

diff  --git a/libcxx/include/cfenv b/libcxx/include/cfenv
index e42b46680d15..16b3761ee27b 100644
--- a/libcxx/include/cfenv
+++ b/libcxx/include/cfenv
@@ -54,8 +54,17 @@ int feupdateenv(const fenv_t* envp);
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+
 #include <fenv.h>
 
+#ifndef _LIBCPP_FENV_H
+#   error <cfenv> tried including <fenv.h> but didn't find libc++'s <fenv.h> header. \
+          This usually means that your header search paths are not configured properly. \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library, and you are probably using compiler flags that make that \
+          not be the case.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif

diff  --git a/libcxx/include/cfloat b/libcxx/include/cfloat
index 36a7c51cdda5..4f991dd49ff4 100644
--- a/libcxx/include/cfloat
+++ b/libcxx/include/cfloat
@@ -71,8 +71,17 @@ Macros:
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+
 #include <float.h>
 
+#ifndef _LIBCPP_FLOAT_H
+#   error <cfloat> tried including <float.h> but didn't find libc++'s <float.h> header. \
+          This usually means that your header search paths are not configured properly. \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library, and you are probably using compiler flags that make that \
+          not be the case.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif

diff  --git a/libcxx/include/cinttypes b/libcxx/include/cinttypes
index a4cfe961cc55..09304460986a 100644
--- a/libcxx/include/cinttypes
+++ b/libcxx/include/cinttypes
@@ -237,8 +237,17 @@ uintmax_t wcstoumax(const wchar_t* restrict nptr, wchar_t** restrict endptr, int
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <cstdint>
+
 #include <inttypes.h>
 
+#ifndef _LIBCPP_INTTYPES_H
+#   error <cinttypes> tried including <inttypes.h> but didn't find libc++'s <inttypes.h> header. \
+          This usually means that your header search paths are not configured properly. \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library, and you are probably using compiler flags that make that \
+          not be the case.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif

diff  --git a/libcxx/include/climits b/libcxx/include/climits
index 16800a652f6d..d773af50d299 100644
--- a/libcxx/include/climits
+++ b/libcxx/include/climits
@@ -39,8 +39,17 @@ Macros:
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+
 #include <limits.h>
 
+#ifndef _LIBCPP_LIMITS_H
+#   error <climits> tried including <limits.h> but didn't find libc++'s <limits.h> header. \
+          This usually means that your header search paths are not configured properly. \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library, and you are probably using compiler flags that make that \
+          not be the case.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif

diff  --git a/libcxx/include/clocale b/libcxx/include/clocale
index 892604207532..e2ace355d7b6 100644
--- a/libcxx/include/clocale
+++ b/libcxx/include/clocale
@@ -36,8 +36,17 @@ lconv* localeconv();
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+
 #include <locale.h>
 
+#ifndef _LIBCPP_LOCALE_H
+#   error <clocale> tried including <locale.h> but didn't find libc++'s <locale.h> header. \
+          This usually means that your header search paths are not configured properly. \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library, and you are probably using compiler flags that make that \
+          not be the case.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif

diff  --git a/libcxx/include/cmath b/libcxx/include/cmath
index 65a853165a98..ef3a67843e10 100644
--- a/libcxx/include/cmath
+++ b/libcxx/include/cmath
@@ -306,10 +306,19 @@ constexpr long double lerp(long double a, long double b, long double t) noexcept
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
-#include <math.h>
 #include <type_traits>
 #include <version>
 
+#include <math.h>
+
+#ifndef _LIBCPP_MATH_H
+#   error <cmath> tried including <math.h> but didn't find libc++'s <math.h> header. \
+          This usually means that your header search paths are not configured properly. \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library, and you are probably using compiler flags that make that \
+          not be the case.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif

diff  --git a/libcxx/include/csetjmp b/libcxx/include/csetjmp
index 4f40bcbf61e9..4c64e8327e3f 100644
--- a/libcxx/include/csetjmp
+++ b/libcxx/include/csetjmp
@@ -32,8 +32,17 @@ void longjmp(jmp_buf env, int val);
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+
 #include <setjmp.h>
 
+#ifndef _LIBCPP_SETJMP_H
+#   error <csetjmp> tried including <setjmp.h> but didn't find libc++'s <setjmp.h> header. \
+          This usually means that your header search paths are not configured properly. \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library, and you are probably using compiler flags that make that \
+          not be the case.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif

diff  --git a/libcxx/include/cstddef b/libcxx/include/cstddef
index 7be4348038e1..e3c066917570 100644
--- a/libcxx/include/cstddef
+++ b/libcxx/include/cstddef
@@ -38,9 +38,18 @@ Types:
 #include <__type_traits/enable_if.h>
 #include <__type_traits/integral_constant.h>
 #include <__type_traits/is_integral.h>
-#include <stddef.h>
 #include <version>
 
+#include <stddef.h>
+
+#ifndef _LIBCPP_STDDEF_H
+#   error <cstddef> tried including <stddef.h> but didn't find libc++'s <stddef.h> header. \
+          This usually means that your header search paths are not configured properly. \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library, and you are probably using compiler flags that make that \
+          not be the case.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif

diff  --git a/libcxx/include/cstdint b/libcxx/include/cstdint
index 83cda947b497..829d9398f387 100644
--- a/libcxx/include/cstdint
+++ b/libcxx/include/cstdint
@@ -142,8 +142,17 @@ Types:
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+
 #include <stdint.h>
 
+#ifndef _LIBCPP_STDINT_H
+#   error <cstdint> tried including <stdint.h> but didn't find libc++'s <stdint.h> header. \
+          This usually means that your header search paths are not configured properly. \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library, and you are probably using compiler flags that make that \
+          not be the case.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif

diff  --git a/libcxx/include/cstdio b/libcxx/include/cstdio
index d191086a85da..221b0b314cf9 100644
--- a/libcxx/include/cstdio
+++ b/libcxx/include/cstdio
@@ -97,8 +97,17 @@ void perror(const char* s);
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+
 #include <stdio.h>
 
+#ifndef _LIBCPP_STDIO_H
+#   error <cstdio> tried including <stdio.h> but didn't find libc++'s <stdio.h> header. \
+          This usually means that your header search paths are not configured properly. \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library, and you are probably using compiler flags that make that \
+          not be the case.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif

diff  --git a/libcxx/include/cstdlib b/libcxx/include/cstdlib
index 457c31f625d8..25c9de5165c2 100644
--- a/libcxx/include/cstdlib
+++ b/libcxx/include/cstdlib
@@ -83,8 +83,17 @@ void *aligned_alloc(size_t alignment, size_t size);                       // C11
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+
 #include <stdlib.h>
 
+#ifndef _LIBCPP_STDLIB_H
+#   error <cstdlib> tried including <stdlib.h> but didn't find libc++'s <stdlib.h> header. \
+          This usually means that your header search paths are not configured properly. \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library, and you are probably using compiler flags that make that \
+          not be the case.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif

diff  --git a/libcxx/include/cstring b/libcxx/include/cstring
index 37c92e149b8f..42bbe73924d3 100644
--- a/libcxx/include/cstring
+++ b/libcxx/include/cstring
@@ -58,8 +58,17 @@ size_t strlen(const char* s);
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+
 #include <string.h>
 
+#ifndef _LIBCPP_STRING_H
+#   error <cstring> tried including <string.h> but didn't find libc++'s <string.h> header. \
+          This usually means that your header search paths are not configured properly. \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library, and you are probably using compiler flags that make that \
+          not be the case.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif

diff  --git a/libcxx/include/cuchar b/libcxx/include/cuchar
index a4ed585d1aeb..b685f470301d 100644
--- a/libcxx/include/cuchar
+++ b/libcxx/include/cuchar
@@ -36,8 +36,17 @@ size_t c32rtomb(char* s, char32_t c32, mbstate_t* ps);
 
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
+
 #include <uchar.h>
 
+#ifndef _LIBCPP_UCHAR_H
+#   error <cuchar> tried including <uchar.h> but didn't find libc++'s <uchar.h> header. \
+          This usually means that your header search paths are not configured properly. \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library, and you are probably using compiler flags that make that \
+          not be the case.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif

diff  --git a/libcxx/include/cwchar b/libcxx/include/cwchar
index 5c69ab2a7bb1..220c817072de 100644
--- a/libcxx/include/cwchar
+++ b/libcxx/include/cwchar
@@ -105,8 +105,17 @@ size_t wcsrtombs(char* restrict dst, const wchar_t** restrict src, size_t len,
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <cwctype>
+
 #include <wchar.h>
 
+#ifndef _LIBCPP_WCHAR_H
+#   error <cwchar> tried including <wchar.h> but didn't find libc++'s <wchar.h> header. \
+          This usually means that your header search paths are not configured properly. \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library, and you are probably using compiler flags that make that \
+          not be the case.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif

diff  --git a/libcxx/include/cwctype b/libcxx/include/cwctype
index 429b00c2446d..5a2d2427d847 100644
--- a/libcxx/include/cwctype
+++ b/libcxx/include/cwctype
@@ -52,8 +52,17 @@ wctrans_t wctrans(const char* property);
 #include <__assert> // all public C++ headers provide the assertion handler
 #include <__config>
 #include <cctype>
+
 #include <wctype.h>
 
+#ifndef _LIBCPP_WCTYPE_H
+#   error <cwctype> tried including <wctype.h> but didn't find libc++'s <wctype.h> header. \
+          This usually means that your header search paths are not configured properly. \
+          The header search paths should contain the C++ Standard Library headers before \
+          any C Standard Library, and you are probably using compiler flags that make that \
+          not be the case.
+#endif
+
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
 #  pragma GCC system_header
 #endif


        


More information about the libcxx-commits mailing list