[libcxx-commits] [libcxx] f079946 - [libc++] Use __builtin_expect and __builtin_assume in _LIBCPP_ASSERT

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Tue Mar 29 08:47:10 PDT 2022


Author: Louis Dionne
Date: 2022-03-29T11:46:47-04:00
New Revision: f0799465b2cc25738d7164774926a8ba3a63b98d

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

LOG: [libc++] Use __builtin_expect and __builtin_assume in _LIBCPP_ASSERT

Since we expect the condition to be true most of the time, we might
as well tell the compiler. And when assertions are disabled, we
might as well tell the compiler that it's allowed to assume that
the condition holds.

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

Added: 
    libcxx/test/libcxx/assertions/single_expression.sh.cpp

Modified: 
    libcxx/include/__assert
    libcxx/test/libcxx/containers/sequences/vector/robust_against_adl.pass.cpp

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__assert b/libcxx/include/__assert
index 93669c6a0e357..cb397e41980f5 100644
--- a/libcxx/include/__assert
+++ b/libcxx/include/__assert
@@ -34,9 +34,20 @@
 #endif
 
 #if _LIBCPP_ENABLE_ASSERTIONS
-# define _LIBCPP_ASSERT(expression, message) ((expression) ? (void)0 : ::std::__libcpp_assertion_handler(__FILE__, __LINE__, #expression, message))
+# define _LIBCPP_ASSERT(expression, message)                                        \
+    (__builtin_expect(static_cast<bool>(expression), 1) ?                           \
+      (void)0 :                                                                     \
+      ::std::__libcpp_assertion_handler(__FILE__, __LINE__, #expression, message))
 #else
-# define _LIBCPP_ASSERT(x, m) ((void)0)
+# if __has_builtin(__builtin_assume)
+#   define _LIBCPP_ASSERT(expression, message)                                      \
+      (_LIBCPP_DIAGNOSTIC_PUSH                                                      \
+      _LIBCPP_CLANG_DIAGNOSTIC_IGNORED("-Wassume")                                  \
+      __builtin_assume(static_cast<bool>(expression))                               \
+      _LIBCPP_DIAGNOSTIC_POP)
+# else
+#   define _LIBCPP_ASSERT(expression, message) ((void)0)
+# endif
 #endif
 
 _LIBCPP_BEGIN_NAMESPACE_STD

diff  --git a/libcxx/test/libcxx/assertions/single_expression.sh.cpp b/libcxx/test/libcxx/assertions/single_expression.sh.cpp
new file mode 100644
index 0000000000000..f638d5b3f5d0d
--- /dev/null
+++ b/libcxx/test/libcxx/assertions/single_expression.sh.cpp
@@ -0,0 +1,34 @@
+//===----------------------------------------------------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+// Make sure that _LIBCPP_ASSERT is a single expression. This is useful so we can use
+// it in places that require an expression, such as in a constructor initializer list.
+
+// RUN: %{build} -Wno-macro-redefined -D_LIBCPP_ENABLE_ASSERTIONS=1
+// RUN: %{run}
+
+// RUN: %{build} -Wno-macro-redefined -D_LIBCPP_ENABLE_ASSERTIONS=0
+// RUN: %{run}
+
+// We flag uses of the assertion handler in older dylibs at compile-time to avoid runtime
+// failures when back-deploying.
+// UNSUPPORTED: use_system_cxx_lib && target={{.+}}-apple-macosx{{10.9|10.10|10.11|10.12|10.13|10.14|10.15|11|12}}
+
+#include <__assert>
+#include <cassert>
+
+void f() {
+  int i = (_LIBCPP_ASSERT(true, "message"), 3);
+  assert(i == 3);
+  return _LIBCPP_ASSERT(true, "message");
+}
+
+int main(int, char**) {
+  f();
+  return 0;
+}

diff  --git a/libcxx/test/libcxx/containers/sequences/vector/robust_against_adl.pass.cpp b/libcxx/test/libcxx/containers/sequences/vector/robust_against_adl.pass.cpp
index 706a815919d54..f8a3e4411cae0 100644
--- a/libcxx/test/libcxx/containers/sequences/vector/robust_against_adl.pass.cpp
+++ b/libcxx/test/libcxx/containers/sequences/vector/robust_against_adl.pass.cpp
@@ -7,7 +7,6 @@
 //===----------------------------------------------------------------------===//
 
 // UNSUPPORTED: c++03
-// UNSUPPORTED: debug_level=0, debug_level=1, libcpp-has-assertions
 
 // <vector>
 
@@ -41,7 +40,9 @@ int main(int, char**)
     v.erase(v.begin());
     v.erase(v.begin(), v.end());
 #if TEST_STD_VER >= 14
-    v.swap(w);
+    // TODO: vector::swap is not robust against ADL because we compare allocators, and that
+    //       triggers ADL when looking up operator==.
+    // v.swap(w);
 #endif
     return 0;
 }


        


More information about the libcxx-commits mailing list