Skip to content

[libc++] Decouple iterator_traits test from precise Clang diagnostics #107478

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

Merged
merged 1 commit into from
Sep 6, 2024

Conversation

ldionne
Copy link
Member

@ldionne ldionne commented Sep 5, 2024

This makes the test more robust and prevents it from breaking when the diagnostic changes subtly (e.g. under modules).

@ldionne ldionne requested a review from a team as a code owner September 5, 2024 22:35
@llvmbot llvmbot added the libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. label Sep 5, 2024
@llvmbot
Copy link
Member

llvmbot commented Sep 5, 2024

@llvm/pr-subscribers-libcxx

Author: Louis Dionne (ldionne)

Changes

This makes the test more robust and prevents it from breaking when the diagnostic changes subtly (e.g. under modules).


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

2 Files Affected:

  • (added) libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.compile.pass.cpp (+132)
  • (removed) libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.verify.cpp (-123)
diff --git a/libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.compile.pass.cpp b/libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.compile.pass.cpp
new file mode 100644
index 00000000000000..f4220c59bfb1ea
--- /dev/null
+++ b/libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.compile.pass.cpp
@@ -0,0 +1,132 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+
+// <iterator>
+
+// struct iterator_traits
+// {
+// };
+
+#include <iterator>
+#include <type_traits>
+
+#include "test_macros.h"
+
+template <class...>
+using always_void = void;
+
+#define HAS_XXX(member)                                                                                                \
+  template <class T, class = void>                                                                                     \
+  struct has_##member : std::false_type {};                                                                            \
+  template <class T>                                                                                                   \
+  struct has_##member<T, always_void<typename T::member>> : std::true_type {}
+
+HAS_XXX(difference_type);
+HAS_XXX(value_type);
+HAS_XXX(pointer);
+HAS_XXX(reference);
+HAS_XXX(iterator_category);
+
+struct A {};
+struct NotAnIteratorEmpty {};
+
+struct NotAnIteratorNoDifference {
+  //     typedef int                       difference_type;
+  typedef A value_type;
+  typedef A* pointer;
+  typedef A& reference;
+  typedef std::forward_iterator_tag iterator_category;
+};
+
+struct NotAnIteratorNoValue {
+  typedef int difference_type;
+  //     typedef A                         value_type;
+  typedef A* pointer;
+  typedef A& reference;
+  typedef std::forward_iterator_tag iterator_category;
+};
+
+struct NotAnIteratorNoPointer {
+  typedef int difference_type;
+  typedef A value_type;
+  //     typedef A*                        pointer;
+  typedef A& reference;
+  typedef std::forward_iterator_tag iterator_category;
+};
+
+struct NotAnIteratorNoReference {
+  typedef int difference_type;
+  typedef A value_type;
+  typedef A* pointer;
+  //    typedef A&                        reference;
+  typedef std::forward_iterator_tag iterator_category;
+};
+
+struct NotAnIteratorNoCategory {
+  typedef int difference_type;
+  typedef A value_type;
+  typedef A* pointer;
+  typedef A& reference;
+  //     typedef std::forward_iterator_tag iterator_category;
+};
+
+void test() {
+  {
+    typedef std::iterator_traits<NotAnIteratorEmpty> T;
+    static_assert(!has_difference_type<T>::value, "");
+    static_assert(!has_value_type<T>::value, "");
+    static_assert(!has_pointer<T>::value, "");
+    static_assert(!has_reference<T>::value, "");
+    static_assert(!has_iterator_category<T>::value, "");
+  }
+
+  {
+    typedef std::iterator_traits<NotAnIteratorNoDifference> T;
+    static_assert(!has_difference_type<T>::value, "");
+    static_assert(!has_value_type<T>::value, "");
+    static_assert(!has_pointer<T>::value, "");
+    static_assert(!has_reference<T>::value, "");
+    static_assert(!has_iterator_category<T>::value, "");
+  }
+
+  {
+    typedef std::iterator_traits<NotAnIteratorNoValue> T;
+    static_assert(!has_difference_type<T>::value, "");
+    static_assert(!has_value_type<T>::value, "");
+    static_assert(!has_pointer<T>::value, "");
+    static_assert(!has_reference<T>::value, "");
+    static_assert(!has_iterator_category<T>::value, "");
+  }
+#if TEST_STD_VER <= 17 || !defined(__cpp_lib_concepts)
+  {
+    typedef std::iterator_traits<NotAnIteratorNoPointer> T;
+    static_assert(!has_difference_type<T>::value, "");
+    static_assert(!has_value_type<T>::value, "");
+    static_assert(!has_pointer<T>::value, "");
+    static_assert(!has_reference<T>::value, "");
+    static_assert(!has_iterator_category<T>::value, "");
+  }
+#endif // TEST_STD_VER <= 17 || !defined(__cpp_lib_concepts)
+  {
+    typedef std::iterator_traits<NotAnIteratorNoReference> T;
+    static_assert(!has_difference_type<T>::value, "");
+    static_assert(!has_value_type<T>::value, "");
+    static_assert(!has_pointer<T>::value, "");
+    static_assert(!has_reference<T>::value, "");
+    static_assert(!has_iterator_category<T>::value, "");
+  }
+
+  {
+    typedef std::iterator_traits<NotAnIteratorNoCategory> T;
+    static_assert(!has_difference_type<T>::value, "");
+    static_assert(!has_value_type<T>::value, "");
+    static_assert(!has_pointer<T>::value, "");
+    static_assert(!has_reference<T>::value, "");
+    static_assert(!has_iterator_category<T>::value, "");
+  }
+}
diff --git a/libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.verify.cpp b/libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.verify.cpp
deleted file mode 100644
index f683ae93beac69..00000000000000
--- a/libcxx/test/std/iterators/iterator.primitives/iterator.traits/empty.verify.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-//===----------------------------------------------------------------------===//
-//
-// 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
-//
-//===----------------------------------------------------------------------===//
-
-// <iterator>
-
-// struct iterator_traits
-// {
-// };
-
-#include <iterator>
-#include "test_macros.h"
-
-struct A {};
-struct NotAnIteratorEmpty {};
-
-struct NotAnIteratorNoDifference
-{
-//     typedef int                       difference_type;
-    typedef A                         value_type;
-    typedef A*                        pointer;
-    typedef A&                        reference;
-    typedef std::forward_iterator_tag iterator_category;
-};
-
-struct NotAnIteratorNoValue
-{
-    typedef int                       difference_type;
-//     typedef A                         value_type;
-    typedef A*                        pointer;
-    typedef A&                        reference;
-    typedef std::forward_iterator_tag iterator_category;
-};
-
-struct NotAnIteratorNoPointer
-{
-    typedef int                       difference_type;
-    typedef A                         value_type;
-//     typedef A*                        pointer;
-    typedef A&                        reference;
-    typedef std::forward_iterator_tag iterator_category;
-};
-
-struct NotAnIteratorNoReference
-{
-    typedef int                       difference_type;
-    typedef A                         value_type;
-    typedef A*                        pointer;
-//    typedef A&                        reference;
-    typedef std::forward_iterator_tag iterator_category;
-};
-
-struct NotAnIteratorNoCategory
-{
-    typedef int                       difference_type;
-    typedef A                         value_type;
-    typedef A*                        pointer;
-    typedef A&                        reference;
-//     typedef std::forward_iterator_tag iterator_category;
-};
-
-int main(int, char**)
-{
-    {
-    typedef std::iterator_traits<NotAnIteratorEmpty> T;
-    typedef T::difference_type   DT; // expected-error-re {{no type named 'difference_type' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::value_type        VT; // expected-error-re {{no type named 'value_type' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::pointer           PT; // expected-error-re {{no type named 'pointer' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::reference         RT; // expected-error-re {{no type named 'reference' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    }
-
-    {
-    typedef std::iterator_traits<NotAnIteratorNoDifference> T;
-    typedef T::difference_type   DT; // expected-error-re {{no type named 'difference_type' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::value_type        VT; // expected-error-re {{no type named 'value_type' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::pointer           PT; // expected-error-re {{no type named 'pointer' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::reference         RT; // expected-error-re {{no type named 'reference' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    }
-
-    {
-    typedef std::iterator_traits<NotAnIteratorNoValue> T;
-    typedef T::difference_type   DT; // expected-error-re {{no type named 'difference_type' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::value_type        VT; // expected-error-re {{no type named 'value_type' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::pointer           PT; // expected-error-re {{no type named 'pointer' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::reference         RT; // expected-error-re {{no type named 'reference' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    }
-#if TEST_STD_VER <= 17 || !defined(__cpp_lib_concepts)
-    {
-    typedef std::iterator_traits<NotAnIteratorNoPointer> T;
-    typedef T::difference_type   DT; // expected-error-re {{no type named 'difference_type' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::value_type        VT; // expected-error-re {{no type named 'value_type' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::pointer           PT; // expected-error-re {{no type named 'pointer' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::reference         RT; // expected-error-re {{no type named 'reference' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    }
-#endif // TEST_STD_VER <= 17 || !defined(__cpp_lib_concepts)
-    {
-    typedef std::iterator_traits<NotAnIteratorNoReference> T;
-    typedef T::difference_type   DT; // expected-error-re {{no type named 'difference_type' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::value_type        VT; // expected-error-re {{no type named 'value_type' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::pointer           PT; // expected-error-re {{no type named 'pointer' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::reference         RT; // expected-error-re {{no type named 'reference' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    }
-
-    {
-    typedef std::iterator_traits<NotAnIteratorNoCategory> T;
-    typedef T::difference_type   DT; // expected-error-re {{no type named 'difference_type' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::value_type        VT; // expected-error-re {{no type named 'value_type' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::pointer           PT; // expected-error-re {{no type named 'pointer' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::reference         RT; // expected-error-re {{no type named 'reference' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    typedef T::iterator_category CT; // expected-error-re {{no type named 'iterator_category' in 'std:{{.*}}:iterator_traits<{{.+}}>}}
-    }
-
-  return 0;
-}

This makes the test more robust and prevents it from breaking when
the diagnostic changes subtly (e.g. under modules).
@ldionne ldionne force-pushed the review/decouple-iterator-traits-diag branch from e1fe0c9 to 9b9a764 Compare September 5, 2024 22:37
@ldionne ldionne merged commit 37086ea into llvm:main Sep 6, 2024
60 of 62 checks passed
@ldionne ldionne deleted the review/decouple-iterator-traits-diag branch September 6, 2024 16:12
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.

2 participants