From 6e459e8c2c3369f8ce0eed6c6803cd00fcf8b988 Mon Sep 17 00:00:00 2001 From: Mark de Wever Date: Fri, 2 Feb 2024 20:15:03 +0100 Subject: [PATCH 1/2] [libc++][modules] Guard missing header validation on Windows. On Windows the libc++ test suite sees the MSVC STL headers and may conclude these are libc++ headers when inspecting the name. Modules guard against forgetting to export new headers. Finding MSVC STL's headers gives false positives. Since the CI tests non-Windows platforms too, the validation will be disabled on Windows. Fixes: https://github.com/llvm/llvm-project/issues/79010 --- libcxx/modules/std.compat.cppm.in | 75 ++++++++++++++----------- libcxx/modules/std.cppm.in | 75 ++++++++++++++----------- libcxx/utils/generate_libcxx_cppm_in.py | 23 ++++++-- 3 files changed, 102 insertions(+), 71 deletions(-) diff --git a/libcxx/modules/std.compat.cppm.in b/libcxx/modules/std.compat.cppm.in index 651d6ec7b9fe2..16363711ac762 100644 --- a/libcxx/modules/std.compat.cppm.in +++ b/libcxx/modules/std.compat.cppm.in @@ -46,39 +46,48 @@ module; #endif // *** Headers not yet available *** -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() +// +// This validation is mainly to aid libc++ developers to add modules for new +// headers. On Windows the Windows SDK can be in the include path. This SDK +// contains the MSVC STL headers. This may give false positives when MSVC STL +// provides a header libc++ has not implemented yet. Therefore this validation +// is not done on Windows. +// +#ifndef _WIN32 +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +#endif // _WIN32 export module std.compat; export import std; diff --git a/libcxx/modules/std.cppm.in b/libcxx/modules/std.cppm.in index 6ce8e287737b8..3b59c28482b11 100644 --- a/libcxx/modules/std.cppm.in +++ b/libcxx/modules/std.cppm.in @@ -168,39 +168,48 @@ module; #include // *** Headers not yet available *** -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() -#if __has_include() -# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include() +// +// This validation is mainly to aid libc++ developers to add modules for new +// headers. On Windows the Windows SDK can be in the include path. This SDK +// contains the MSVC STL headers. This may give false positives when MSVC STL +// provides a header libc++ has not implemented yet. Therefore this validation +// is not done on Windows. +// +#ifndef _WIN32 +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +# if __has_include() +# error "please update the header information for in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include() +#endif // _WIN32 export module std; diff --git a/libcxx/utils/generate_libcxx_cppm_in.py b/libcxx/utils/generate_libcxx_cppm_in.py index 2d3f829847fb9..57e1f1a8bbd30 100644 --- a/libcxx/utils/generate_libcxx_cppm_in.py +++ b/libcxx/utils/generate_libcxx_cppm_in.py @@ -57,18 +57,31 @@ def write_file(module): else: module_cpp_in.write(f"#include <{header}>\n") - module_cpp_in.write("\n// *** Headers not yet available ***\n") + module_cpp_in.write( + """ +// *** Headers not yet available *** +// +// This validation is mainly to aid libc++ developers to add modules for new +// headers. On Windows the Windows SDK can be in the include path. This SDK +// contains the MSVC STL headers. This may give false positives when MSVC STL +// provides a header libc++ has not implemented yet. Therefore this validation +// is not done on Windows. +// +#ifndef _WIN32 +""" + ) for header in sorted(headers_not_available): module_cpp_in.write( f"""\ -#if __has_include(<{header}>) -# error "please update the header information for <{header}> in headers_not_available in utils/libcxx/header_information.py" -#endif // __has_include(<{header}>) +# if __has_include(<{header}>) +# error "please update the header information for <{header}> in headers_not_available in utils/libcxx/header_information.py" +# endif // __has_include(<{header}>) """ ) module_cpp_in.write( - f""" + f"""#endif // _WIN32 + export module {module}; {'export import std;' if module == 'std.compat' else ''} From cef37698cbfa30ac61dd32d5466829e1b5f448d5 Mon Sep 17 00:00:00 2001 From: Mark de Wever Date: Fri, 9 Feb 2024 17:41:32 +0100 Subject: [PATCH 2/2] Update libcxx/utils/generate_libcxx_cppm_in.py Co-authored-by: Louis Dionne --- libcxx/utils/generate_libcxx_cppm_in.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libcxx/utils/generate_libcxx_cppm_in.py b/libcxx/utils/generate_libcxx_cppm_in.py index 57e1f1a8bbd30..0390ce5067f40 100644 --- a/libcxx/utils/generate_libcxx_cppm_in.py +++ b/libcxx/utils/generate_libcxx_cppm_in.py @@ -61,11 +61,11 @@ def write_file(module): """ // *** Headers not yet available *** // -// This validation is mainly to aid libc++ developers to add modules for new -// headers. On Windows the Windows SDK can be in the include path. This SDK -// contains the MSVC STL headers. This may give false positives when MSVC STL -// provides a header libc++ has not implemented yet. Therefore this validation -// is not done on Windows. +// This validation is mainly to catch when a new header is added but adding the +// corresponding .inc file is forgotten. However, the check based on __has_include +// alone doesn't work on Windows because the Windows SDK is on the include path, +// and that means the MSVC STL headers can be found as well, tricking __has_include +// into thinking that libc++ provides the header. // #ifndef _WIN32 """