//===----------------------------------------------------------------------===// // // 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 // //===----------------------------------------------------------------------===// // // UNSUPPORTED: c++03, c++11, c++14, c++17, c++20 // This test fails in Windows DLL configurations, due to // __exclude_from_explicit_instantiation__ not behaving as it should in // combination with dllimport (https://llvm.org/PR41018), in combination // with running tests in c++2b mode while building the library in c++20 mode. // // If the library was built in c++2b mode, this test would succeed. // // Older CMake passed -std:c++latest to set C++ 20 mode on clang-cl, which // hid this issue. With newer CMake versions, it passes -std:c++20 which // makes this fail. // // Marking as UNSUPPORTED instead of XFAIL to avoid spurious failures/successes // depending on the version of CMake used. // TODO: Remove this when the library is built in c++2b mode. // // UNSUPPORTED: windows-dll // template > // class basic_ostream; // basic_ostream& operator<<(const volatile void* val); #include #include template class testbuf : public std::basic_streambuf { typedef std::basic_streambuf base; std::basic_string str_; public: testbuf() {} std::basic_string str() const { return std::basic_string(base::pbase(), base::pptr()); } protected: virtual typename base::int_type overflow(typename base::int_type ch = base::traits_type::eof()) { if (ch != base::traits_type::eof()) { int n = static_cast(str_.size()); str_.push_back(static_cast(ch)); str_.resize(str_.capacity()); base::setp(const_cast(str_.data()), const_cast(str_.data() + str_.size())); base::pbump(n + 1); } return ch; } }; int main(int, char**) { testbuf sb1; std::ostream os1(&sb1); int n1; os1 << &n1; assert(os1.good()); std::string s1 = sb1.str(); testbuf sb2; std::ostream os2(&sb2); os2 << static_cast(&n1); assert(os2.good()); std::string s2 = sb2.str(); testbuf sb3; std::ostream os3(&sb3); volatile int n3; os3 << &n3; assert(os3.good()); std::string s3 = sb3.str(); // %p is implementation defined. Instead of validating the // output, at least ensure that it does not generate an empty // string. Also make sure that given two distinct addresses, the // output of %p is different. assert(!s1.empty()); assert(!s2.empty()); assert(s1 == s2); assert(!s3.empty()); assert(s2 != s3); return 0; }