1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9// <ostream>
10
11// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
12
13// This test fails in Windows DLL configurations, due to
14// __exclude_from_explicit_instantiation__ not behaving as it should in
15// combination with dllimport (https://llvm.org/PR41018), in combination
16// with running tests in c++23 mode while building the library in c++20 mode.
17//
18// If the library was built in c++23 mode, this test would succeed.
19//
20// Older CMake passed -std:c++latest to set C++20 mode on clang-cl, which
21// hid this issue. With newer CMake versions, it passes -std:c++20 which
22// makes this fail.
23//
24// Marking as UNSUPPORTED instead of XFAIL to avoid spurious failures/successes
25// depending on the version of CMake used.
26// TODO: Remove this when the library is built in c++23 mode.
27//
28// UNSUPPORTED: windows-dll
29
30// template <class charT, class traits = char_traits<charT> >
31// class basic_ostream;
32
33// basic_ostream& operator<<(const volatile void* val);
34
35#include <ostream>
36#include <cassert>
37
38template <class CharT>
39class testbuf : public std::basic_streambuf<CharT> {
40 typedef std::basic_streambuf<CharT> base;
41 std::basic_string<CharT> str_;
42
43public:
44 testbuf() {}
45
46 std::basic_string<CharT> str() const { return std::basic_string<CharT>(base::pbase(), base::pptr()); }
47
48protected:
49 virtual typename base::int_type overflow(typename base::int_type ch = base::traits_type::eof()) {
50 if (ch != base::traits_type::eof()) {
51 int n = static_cast<int>(str_.size());
52 str_.push_back(static_cast<CharT>(ch));
53 str_.resize(str_.capacity());
54 base::setp(const_cast<CharT*>(str_.data()), const_cast<CharT*>(str_.data() + str_.size()));
55 base::pbump(n + 1);
56 }
57 return ch;
58 }
59};
60
61int main(int, char**) {
62 testbuf<char> sb1;
63 std::ostream os1(&sb1);
64 int n1;
65 os1 << &n1;
66 assert(os1.good());
67 std::string s1 = sb1.str();
68
69 testbuf<char> sb2;
70 std::ostream os2(&sb2);
71 os2 << static_cast<volatile void*>(&n1);
72 assert(os2.good());
73 std::string s2 = sb2.str();
74
75 testbuf<char> sb3;
76 std::ostream os3(&sb3);
77 volatile int n3;
78 os3 << &n3;
79 assert(os3.good());
80 std::string s3 = sb3.str();
81
82 // %p is implementation defined. Instead of validating the
83 // output, at least ensure that it does not generate an empty
84 // string. Also make sure that given two distinct addresses, the
85 // output of %p is different.
86 assert(!s1.empty());
87 assert(!s2.empty());
88 assert(s1 == s2);
89
90 assert(!s3.empty());
91 assert(s2 != s3);
92
93 return 0;
94}
95

source code of libcxx/test/std/input.output/iostream.format/output.streams/ostream.formatted/ostream.inserters.arithmetic/pointer.volatile.pass.cpp