xref: /llvm-project/clang/test/Modules/pr63544.cppm (revision da00c60dae0040185dc45039c4397f6e746548e9)
1// RUN: rm -rf %t
2// RUN: mkdir -p %t
3// RUN: split-file %s %t
4//
5// RUN: %clang_cc1 -std=c++23 %t/a.cppm -emit-module-interface -o %t/m-a.pcm
6// RUN: %clang_cc1 -std=c++23 %t/b.cppm -emit-module-interface -o %t/m-b.pcm
7// RUN: %clang_cc1 -std=c++23 %t/m.cppm -emit-module-interface -o %t/m.pcm \
8// RUN:     -fprebuilt-module-path=%t
9// RUN: %clang_cc1 -std=c++23 %t/pr63544.cpp -fprebuilt-module-path=%t -fsyntax-only -verify
10
11// Test again with reduced BMI.
12// RUN: rm -rf %t
13// RUN: mkdir -p %t
14// RUN: split-file %s %t
15//
16// RUN: %clang_cc1 -std=c++23 %t/a.cppm -emit-reduced-module-interface -o %t/m-a.pcm
17// RUN: %clang_cc1 -std=c++23 %t/b.cppm -emit-reduced-module-interface -o %t/m-b.pcm
18// RUN: %clang_cc1 -std=c++23 %t/m.cppm -emit-reduced-module-interface -o %t/m.pcm \
19// RUN:     -fprebuilt-module-path=%t
20// RUN: %clang_cc1 -std=c++23 %t/pr63544.cpp -fprebuilt-module-path=%t -fsyntax-only -verify
21
22
23//--- foo.h
24
25namespace std {
26struct strong_ordering {
27  int n;
28  constexpr operator int() const { return n; }
29  static const strong_ordering equal, greater, less;
30};
31constexpr strong_ordering strong_ordering::equal = {0};
32constexpr strong_ordering strong_ordering::greater = {1};
33constexpr strong_ordering strong_ordering::less = {-1};
34} // namespace std
35
36namespace std {
37template <typename _Tp>
38class optional {
39private:
40    using value_type = _Tp;
41    value_type __val_;
42    bool __engaged_;
43public:
44    constexpr bool has_value() const noexcept
45    {
46        return this->__engaged_;
47    }
48
49    constexpr const value_type& operator*() const& noexcept
50    {
51        return __val_;
52    }
53
54    optional(_Tp v) : __val_(v) {
55        __engaged_ = true;
56    }
57};
58
59template <class _Tp>
60concept __is_derived_from_optional = requires(const _Tp& __t) { []<class __Up>(const optional<__Up>&) {}(__t); };
61
62template <class _Tp, class _Up>
63    requires(!__is_derived_from_optional<_Up>)
64constexpr strong_ordering
65operator<=>(const optional<_Tp>& __x, const _Up& __v) {
66    return __x.has_value() ? *__x <=> __v : strong_ordering::less;
67}
68} // namespace std
69
70//--- a.cppm
71module;
72#include "foo.h"
73export module m:a;
74export namespace std {
75    using std::optional;
76    using std::operator<=>;
77}
78
79//--- b.cppm
80module;
81#include "foo.h"
82export module m:b;
83export namespace std {
84    using std::optional;
85    using std::operator<=>;
86}
87
88//--- m.cppm
89export module m;
90export import :a;
91export import :b;
92
93//--- pr63544.cpp
94// expected-no-diagnostics
95import m;
96int pr63544() {
97    std::optional<int> a(43);
98    int t{3};
99    return a<=>t;
100}
101