On 19/12/24 14:49 +0100, Giuseppe D'Angelo wrote:
diff --git a/libstdc++-v3/testsuite/23_containers/span/init_list_cons_neg.cc 
b/libstdc++-v3/testsuite/23_containers/span/init_list_cons_neg.cc
new file mode 100644
index 00000000000..ef43541b769
--- /dev/null
+++ b/libstdc++-v3/testsuite/23_containers/span/init_list_cons_neg.cc
@@ -0,0 +1,31 @@
+// { dg-do run { target c++20 } }
+
+#include <span>
+#include <utility>
+#include <any>
+
+#include <testsuite_hooks.h>
+
+// Examples from P2447R4
+void one(std::pair<int, int>) {}
+void one(std::span<const int>) {}
+void two(std::span<const int, 2>) {}
+constexpr std::size_t three(std::span<void * const> v) { return v.size(); }
+constexpr std::size_t four(std::span<const std::any> v) { return v.size(); }
+
+int main()
+{
+  one({1, 2}); // { dg-error "call of overloaded" "should be ambiguous with the 
one(std::pair) overload" { target c++26 } }
+  two({{1, 2}}); // { dg-error "would use explicit constructor" "should prefer the 
initializer_list constructor, which is explicit" { target c++26 } }
+
+  void *array3[10];
+  std::any array4[10];
+
+#if __cpp_lib_span_initializer_list
+  static_assert(three({array3, 0}) == 2);
+  VERIFY(four({array4, array4 + 10}) == 2);

This runtime VERIFY assertion doesn't make sense because the file
doesn't compile at all in C++26 mode, it fails due to the errors
above.

+#else
+  static_assert(three({array3, 0}) == 0);
+  VERIFY(four({array4, array4 + 10}) == 10);
+#endif
+}
--
2.34.1


I'm seeing failures for this new test when compiled as C++26, e.g.
when using

GLIBCXX_TESTSUITE_STDS=20,23,26 make check 
RUNTESTFLAGS="conformance.exp=23_containers/span/init_list_cons_neg.cc -a"

The results are:

PASS: 23_containers/span/init_list_cons_neg.cc  -std=gnu++20 (test for excess 
errors)
PASS: 23_containers/span/init_list_cons_neg.cc  -std=gnu++20 execution test
PASS: 23_containers/span/init_list_cons_neg.cc  -std=gnu++23 (test for excess 
errors)
PASS: 23_containers/span/init_list_cons_neg.cc  -std=gnu++23 execution test
PASS: 23_containers/span/init_list_cons_neg.cc  -std=gnu++26 should be 
ambiguous with the one(std::pair) overload (test for errors, line 18)
PASS: 23_containers/span/init_list_cons_neg.cc  -std=gnu++26 should prefer the 
initializer_list constructor, which is explicit (test for errors, line 19)
PASS: 23_containers/span/init_list_cons_neg.cc  -std=gnu++26 (test for excess 
errors)
UNRESOLVED: 23_containers/span/init_list_cons_neg.cc  -std=gnu++26 compilation 
failed to produce executable

The problem is that { dg-do run ... } means that dejagnu expects the
file to compile and run, but it fails to compile for C++26 so cannot
be run.

I think what's needed is:

// { dg-do run { target { c++20 && c++23_down } } }
// { dg-do compile { target c++26 } }

This makes it a compile+link+run test for C++20/23 but only a compile
test for C++26, so it won't complain about it being UNRESOLVED for the
run step.


To solve the problem of the VERIFY not being checked for C++26, let's
repalce std::any with a constexpr-compatible Any type and move the
arrays to namespace scope, like so:

// { dg-do run { target { c++20 && c++23_down } } }
// { dg-do compile { target c++26 } }

#include <span>
#include <utility>

#include <testsuite_hooks.h>

struct Any {
  constexpr Any() { }
  template<typename T> constexpr Any(T) { }
};

// Examples from P2447R4
void one(std::pair<int, int>) {}
void one(std::span<const int>) {}
void two(std::span<const int, 2>) {}
constexpr std::size_t three(std::span<void * const> v) { return v.size(); }
constexpr std::size_t four(std::span<const Any> v) { return v.size(); }

void *array3[10];
Any array4[10];

int main()
{
  one({1, 2}); // { dg-error "call of overloaded" "should be ambiguous with the 
one(std::pair) overload" { target c++26 } }
  two({{1, 2}}); // { dg-error "would use explicit constructor" "should prefer the 
initializer_list constructor, which is explicit" { target c++26 } }

#if __cpp_lib_span_initializer_list
  static_assert(three({array3, 0}) == 2);
  static_assert(four({array4, array4 + 10}) == 2);
#else
  static_assert(three({array3, 0}) == 0);
  static_assert(four({array4, array4 + 10}) == 10);
#endif
}

With this, I get seven PASS results for this test.


Reply via email to