Skip to content

Revert "[libc++] Allow the use of extensions in the implementation (#79532)" #85792

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 4 commits into from

Conversation

sam-mccall
Copy link
Collaborator

This reverts commit 4d323e4.

The heavy use of push/pop directives causes a severe compile-time
regression (>50%) when building code that uses libc++ via modules.

See discussion on #79532

…lvm#79532)"

This reverts commit 4d323e4.

The heavy use of push/pop directives causes a severe compile-time
regression (>50%) when building code that uses libc++ via modules.

See discussion on llvm#79532
@sam-mccall sam-mccall requested a review from a team as a code owner March 19, 2024 14:08
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Mar 19, 2024
@llvmbot
Copy link
Member

llvmbot commented Mar 19, 2024

@llvm/pr-subscribers-libcxx

Author: Sam McCall (sam-mccall)

Changes

This reverts commit 4d323e4.

The heavy use of push/pop directives causes a severe compile-time
regression (>50%) when building code that uses libc++ via modules.

See discussion on #79532


Full diff: https://github.com/llvm/llvm-project/pull/85792.diff

2 Files Affected:

  • (modified) libcxx/include/__config (+20-41)
  • (modified) libcxx/include/tuple (+6)
diff --git a/libcxx/include/__config b/libcxx/include/__config
index 11e13e0c24986a..3a438e85a7b819 100644
--- a/libcxx/include/__config
+++ b/libcxx/include/__config
@@ -406,10 +406,6 @@ _LIBCPP_HARDENING_MODE_DEBUG
 #    define __has_include(...) 0
 #  endif
 
-#  ifndef __has_warning
-#    define __has_warning(...) 0
-#  endif
-
 #  if !defined(_LIBCPP_COMPILER_CLANG_BASED) && __cplusplus < 201103L
 #    error "libc++ only supports C++03 with Clang-based compilers. Please enable C++11"
 #  endif
@@ -727,23 +723,6 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_EXCLUDE_FROM_EXPLICIT_INSTANTIATION _LIBCPP_ALWAYS_INLINE
 #  endif
 
-#  ifdef _LIBCPP_COMPILER_CLANG_BASED
-#    define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
-#    define _LIBCPP_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
-#    define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(clang diagnostic ignored str))
-#    define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str)
-#  elif defined(_LIBCPP_COMPILER_GCC)
-#    define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
-#    define _LIBCPP_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
-#    define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str)
-#    define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(GCC diagnostic ignored str))
-#  else
-#    define _LIBCPP_DIAGNOSTIC_PUSH
-#    define _LIBCPP_DIAGNOSTIC_POP
-#    define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str)
-#    define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str)
-#  endif
-
 #  if _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_FAST
 #    define _LIBCPP_HARDENING_SIG f
 #  elif _LIBCPP_HARDENING_MODE == _LIBCPP_HARDENING_MODE_EXTENSIVE
@@ -831,33 +810,16 @@ typedef __char32_t char32_t;
 #    define _LIBCPP_HIDE_FROM_ABI_AFTER_V1 _LIBCPP_HIDE_FROM_ABI
 #  endif
 
-// TODO: Remove this workaround once we drop support for Clang 16
-#if __has_warning("-Wc++23-extensions")
-#  define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED_CXX23_EXTENSION _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++23-extensions")
-#else
-#  define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED_CXX23_EXTENSION _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++2b-extensions")
-#endif
-
 // Inline namespaces are available in Clang/GCC/MSVC regardless of C++ dialect.
 // clang-format off
-#  define _LIBCPP_BEGIN_NAMESPACE_STD _LIBCPP_DIAGNOSTIC_PUSH                                                          \
-                                      _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++11-extensions")                           \
-                                      _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++14-extensions")                           \
-                                      _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++17-extensions")                           \
-                                      _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++20-extensions")                           \
-                                      _LIBCPP_CLANG_DIAGNOSTIC_IGNORED_CXX23_EXTENSION                                 \
-                                      _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++14-extensions")                             \
-                                      _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++17-extensions")                             \
-                                      _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++20-extensions")                             \
-                                      _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++23-extensions")                             \
-                                      namespace _LIBCPP_TYPE_VISIBILITY_DEFAULT std {                                  \
+#  define _LIBCPP_BEGIN_NAMESPACE_STD namespace _LIBCPP_TYPE_VISIBILITY_DEFAULT std {                                  \
                                inline namespace _LIBCPP_ABI_NAMESPACE {
-#  define _LIBCPP_END_NAMESPACE_STD }} _LIBCPP_DIAGNOSTIC_POP
+#  define _LIBCPP_END_NAMESPACE_STD }}
 
 #  define _LIBCPP_BEGIN_NAMESPACE_FILESYSTEM _LIBCPP_BEGIN_NAMESPACE_STD                                               \
                                              inline namespace __fs { namespace filesystem {
 
-#  define _LIBCPP_END_NAMESPACE_FILESYSTEM }} _LIBCPP_END_NAMESPACE_STD
+#  define _LIBCPP_END_NAMESPACE_FILESYSTEM _LIBCPP_END_NAMESPACE_STD }}
 // clang-format on
 
 #  if __has_attribute(__enable_if__)
@@ -1294,6 +1256,23 @@ __sanitizer_verify_double_ended_contiguous_container(const void*, const void*, c
 // the ABI inconsistent.
 #  endif
 
+#  ifdef _LIBCPP_COMPILER_CLANG_BASED
+#    define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push")
+#    define _LIBCPP_DIAGNOSTIC_POP _Pragma("clang diagnostic pop")
+#    define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(clang diagnostic ignored str))
+#    define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str)
+#  elif defined(_LIBCPP_COMPILER_GCC)
+#    define _LIBCPP_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push")
+#    define _LIBCPP_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop")
+#    define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str)
+#    define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str) _Pragma(_LIBCPP_TOSTRING(GCC diagnostic ignored str))
+#  else
+#    define _LIBCPP_DIAGNOSTIC_PUSH
+#    define _LIBCPP_DIAGNOSTIC_POP
+#    define _LIBCPP_CLANG_DIAGNOSTIC_IGNORED(str)
+#    define _LIBCPP_GCC_DIAGNOSTIC_IGNORED(str)
+#  endif
+
 // c8rtomb() and mbrtoc8() were added in C++20 and C23. Support for these
 // functions is gradually being added to existing C libraries. The conditions
 // below check for known C library versions and conditions under which these
diff --git a/libcxx/include/tuple b/libcxx/include/tuple
index f78db061b844b0..8e38dfe4d0eaa8 100644
--- a/libcxx/include/tuple
+++ b/libcxx/include/tuple
@@ -540,6 +540,10 @@ class _LIBCPP_TEMPLATE_VIS tuple {
 public:
   // [tuple.cnstr]
 
+  _LIBCPP_DIAGNOSTIC_PUSH
+  _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wc++20-extensions")
+  _LIBCPP_GCC_DIAGNOSTIC_IGNORED("-Wc++20-extensions")
+
   // tuple() constructors (including allocator_arg_t variants)
   template <template <class...> class _IsImpDefault                = __is_implicitly_default_constructible,
             template <class...> class _IsDefault                   = is_default_constructible,
@@ -821,6 +825,8 @@ public:
       : __base_(allocator_arg_t(), __alloc, std::move(__p)) {}
 #  endif // _LIBCPP_STD_VER >= 23
 
+  _LIBCPP_DIAGNOSTIC_POP
+
   // [tuple.assign]
   _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_SINCE_CXX20 tuple&
   operator=(_If<_And<is_copy_assignable<_Tp>...>::value, tuple, __nat> const& __tuple)

@sam-mccall
Copy link
Collaborator Author

#79532 has details on the regression.

It seems there are other ways to allow extensions broadly without using push/pop everywhere. But there hasn't been any movement there so far, and this is a large enough compile performance regression that we can't ship libc++.

Contra #79532 (comment), a clean revert seems to pass tests, so I don't think this is heavily used yet.
So I'd like to revert this until it's clear what the best way to enable this is.

@sam-mccall
Copy link
Collaborator Author

Fixed a failure that showed up presubmit: "pair" is using explicit(bool) and needs a suppression similar to the one in tuple. So this is no longer a pure revert. (not sure why I didn't see this locally).

Copy link

github-actions bot commented Mar 19, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@ldionne
Copy link
Member

ldionne commented Mar 19, 2024

I would support the revert until we understand the issue better and how to fix it. 50% regression is... very serious. Especially given all the efforts we do to reduce compile times by a few percentage points.

I'll let Nikolas have a look but that's my opinion.

@ldionne
Copy link
Member

ldionne commented Mar 19, 2024

I see other solutions being mentioned in #79532 though, should we be exploring those instead?

@frederick-vs-ja
Copy link
Contributor

frederick-vs-ja commented Mar 20, 2024

When building modules, it shouldn't be needed to suppress warnings on C++14/17/20 features, right?

I'd expect that C++23 features are rarely used as extensions (or not yet used), so we might be able to suppress the warnings more locally.

@sam-mccall
Copy link
Collaborator Author

Thanks!

I see other solutions being mentioned in #79532 though, should we be exploring those instead?

It seems like there are several options with tradeoffs, and I don't feel informed enough to push for one of them. If someone closer to the project can make the call then absolutely.

If there's still some discussion to be had, I'd be grateful if we could revert back to a good state first.
(We consume libc++ close to head, so we'll have to start carrying a downstream patch for this soon, which is no fun).

@frederick-vs-ja

When building modules, it shouldn't be needed to suppress warnings on C++14/17/20 features, right?

Mostly. (You can use Clang modules without C++20, but I think the relatively-few who did that are on C++20 now anyway). You could reduce the suppression pragmas this way (could gate on language version rather than modules-enabled?). But it also feels like a short-term fix to what may simply be the wrong mechanism.

@mordante
Copy link
Member

I would also support a revert until we can found out what caused the regression.

@sam-mccall what modules are you talking about Clang modules or C++20 modules?

@philnik777
Copy link
Contributor

#85917 is an (IMO simpler) alternative to work around this problem.

@sam-mccall
Copy link
Collaborator Author

@sam-mccall what modules are you talking about Clang modules or C++20 modules?

Our deployment is Clang modules (which would also count as C++20 header units IIUC). My reading of the code is that diagnostic mappings take the same codepath in both cases. I don't have a large-scale C++20 modules codebase with libc++ set up as named modules to test on.

#85917 is an (IMO simpler) alternative to work around this problem.

I'm happy if that lands instead, that will also fix our compile time :-) It is important that it should fire when clang modules are on and c++20 modules are off (which __has_feature(modules) indeed does).

(Personally I find this solution a bit iffy: we've added a bunch of load onto a compiler subsystem, and immediately found circumstances where that causes problems - it seems more robust to remove the load than to patch around those circumstances. But that's a concern for owners - this will solve my immediate problem)

@mordante
Copy link
Member

@sam-mccall what modules are you talking about Clang modules or C++20 modules?

Our deployment is Clang modules (which would also count as C++20 header units IIUC). My reading of the code is that diagnostic mappings take the same codepath in both cases. I don't have a large-scale C++20 modules codebase with libc++ set up as named modules to test on.

Thanks! I was just confused whether this is related to Clang or C++ modules.

@ldionne
Copy link
Member

ldionne commented Mar 23, 2024

(Personally I find this solution a bit iffy: we've added a bunch of load onto a compiler subsystem, and immediately found circumstances where that causes problems - it seems more robust to remove the load than to patch around those circumstances. But that's a concern for owners - this will solve my immediate problem)

At the same time, we do want the ability to use extensions in the code base, which this revert prevents.

@philnik777
Copy link
Contributor

Closing this, since #85917 has landed.

@philnik777 philnik777 closed this Mar 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants