[clang] Implement lifetime analysis for lifetime_capture_by(X) (#115921)
[llvm-project.git] / clang / test / Modules / pair-unambiguous-ctor.cppm
blob24fb15959577b0f79b35f270346065c37f888c68
1 // Test case reduced from an experimental std modules implementation.
2 // Tests that the compiler don't emit confusing error about the ambiguous ctor
3 // about std::pair.
4 //
5 // RUN: rm -fr %t
6 // RUN: mkdir %t
7 // RUN: split-file %s %t
8 //
9 // RUN: %clang_cc1 -std=c++20 %t/string.cppm -I%t -emit-module-interface -o %t/std-string.pcm
10 // RUN: %clang_cc1 -std=c++20 %t/algorithm.cppm -I%t -emit-module-interface -o %t/std-algorithm.pcm
11 // RUN: %clang_cc1 -std=c++20 %t/Use.cppm -I%t -fprebuilt-module-path=%t -emit-module-interface -verify -o %t/Use.pcm
13 // Test again with reduced BMI.
14 // RUN: rm -fr %t
15 // RUN: mkdir %t
16 // RUN: split-file %s %t
18 // RUN: %clang_cc1 -std=c++20 %t/string.cppm -I%t -emit-reduced-module-interface -o %t/std-string.pcm
19 // RUN: %clang_cc1 -std=c++20 %t/algorithm.cppm -I%t -emit-reduced-module-interface -o %t/std-algorithm.pcm
20 // RUN: %clang_cc1 -std=c++20 %t/Use.cppm -I%t -fprebuilt-module-path=%t -emit-reduced-module-interface -verify -o %t/Use.pcm
22 //--- Use.cppm
23 // expected-no-diagnostics
24 module;
25 #include "config.h"
26 # 3 "pair-unambiguous-ctor.cppm" 1 3
27 export module std:M;
28 # 3 "pair-unambiguous-ctor.cppm" 2 3
29 import :string;
30 import :algorithm;
32 auto check() {
33     return std::string();
36 //--- string.cppm
37 module;
38 #include "string.h"
39 # 28 "pair-unambiguous-ctor.cppm" 1 3
40 export module std:string;
41 export namespace std {
42     using std::string;
44 # 28 "pair-unambiguous-ctor.cppm" 2 3
46 //--- algorithm.cppm
47 module;
48 #include "algorithm.h"
49 # 38 "pair-unambiguous-ctor.cppm" 1 3
50 export module std:algorithm;
51 # 38 "pair-unambiguous-ctor.cppm" 2 3
53 //--- pair.h
54 namespace std __attribute__ ((__visibility__ ("default")))
55
56   typedef long unsigned int size_t;
57   typedef long int ptrdiff_t;
59   typedef decltype(nullptr) nullptr_t;
61   template<typename _Tp, _Tp __v>
62     struct integral_constant
63     {
64       static constexpr _Tp value = __v;
65       typedef _Tp value_type;
66       typedef integral_constant<_Tp, __v> type;
67       constexpr operator value_type() const noexcept { return value; }
68       constexpr value_type operator()() const noexcept { return value; }
69     };
71   template<typename _Tp, _Tp __v>
72     constexpr _Tp integral_constant<_Tp, __v>::value;
74   typedef integral_constant<bool, true> true_type;
75   typedef integral_constant<bool, false> false_type;
77   template<bool __v>
78     using __bool_constant = integral_constant<bool, __v>;
81   template<bool, typename, typename>
82     struct conditional;
84   template<bool _Cond, typename _Iftrue, typename _Iffalse>
85     struct conditional
86     { typedef _Iftrue type; };
88   template<typename _Iftrue, typename _Iffalse>
89     struct conditional<false, _Iftrue, _Iffalse>
90     { typedef _Iffalse type; };
93   template<bool, typename _Tp = void>
94     struct enable_if
95     { };
98   template<typename _Tp>
99     struct enable_if<true, _Tp>
100     { typedef _Tp type; };
102   template<typename _Tp, typename... _Args>
103     struct __is_constructible_impl
104     : public __bool_constant<__is_constructible(_Tp, _Args...)>
105     { };
108   template<typename _Tp, typename... _Args>
109     struct is_constructible
110       : public __is_constructible_impl<_Tp, _Args...>
111     {};
113   template<typename>
114     struct __is_void_helper
115     : public false_type { };
117   template<>
118     struct __is_void_helper<void>
119     : public true_type { };
121   template<typename _Tp>
122     struct is_void
123     : public __is_void_helper<_Tp>::type
124     { };
126   template<typename...>
127     class tuple;
129   template<std::size_t...>
130     struct _Index_tuple;
132   template <bool, typename _T1, typename _T2>
133     struct _PCC
134     {
135       template <typename _U1, typename _U2>
136       static constexpr bool _ConstructiblePair()
137       {
138  return is_constructible<_T1, const _U1&>::value;
139       }
141   };
143   template<typename _T1, typename _T2>
144     struct pair
145     {
146       typedef _T1 first_type;
147       typedef _T2 second_type;
149       _T1 first;
150       _T2 second;
152       using _PCCP = _PCC<true, _T1, _T2>;
154       template<typename _U1 = _T1, typename _U2=_T2, typename
155         enable_if<_PCCP::template
156       _ConstructiblePair<_U1, _U2>(),
157                          bool>::type=true>
158       constexpr pair(const _T1& __a, const _T2& __b)
159       : first(__a), second(__b) { }
161       constexpr pair&
162       operator=(typename conditional<
163          is_constructible<_T2>::value,
164   const pair&, nullptr_t>::type __p)
165       {
166  first = __p.first;
167  second = __p.second;
168  return *this;
169       }
171     private:
172       template<typename... _Args1, std::size_t... _Indexes1,
173                typename... _Args2, std::size_t... _Indexes2>
174       constexpr
175       pair(tuple<_Args1...>&, tuple<_Args2...>&,
176            _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);
178     };
180   template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>;
183 //--- string.h
184 #include "pair.h"
186 namespace std __attribute__ ((__visibility__ ("default")))
188   class __undefined;
190   template<typename _Tp>
191     using __make_not_void
192       = typename conditional<is_void<_Tp>::value, __undefined, _Tp>::type;
194   template <typename Ptr>
195   struct pointer_traits {};
196   
197   template<typename _Tp>
198     struct pointer_traits<_Tp*>
199     {
201       typedef _Tp* pointer;
203       typedef _Tp element_type;
205       static constexpr pointer
206       pointer_to(__make_not_void<element_type>& __r) noexcept
207       { return __builtin_addressof(__r); }
208     };
210   template<typename _Tp>
211     class allocator;
213   template<typename _Alloc>
214     struct allocator_traits;
216   template<typename _Tp>
217     struct allocator_traits<allocator<_Tp>>
218     {
219       using pointer = _Tp*;
220     };
222   template<typename _Alloc>
223   struct __alloc_traits
224   : std::allocator_traits<_Alloc>
225   {
226     typedef std::allocator_traits<_Alloc> _Base_type;
227     typedef typename _Base_type::pointer pointer;
228   };
230   template<class _CharT>
231     struct char_traits;
233   template<typename _CharT, typename _Traits = char_traits<_CharT>,
234            typename _Alloc = allocator<_CharT> >
235     class basic_string
236     {
237       typedef std::__alloc_traits<_Alloc> _Alloc_traits;
239     public:
240       typedef typename _Alloc_traits::pointer pointer;
242     private:
243       pointer _M_dataplus;
244       _CharT _M_local_buf[16];
246       pointer
247       _M_local_data()
248       {
249         return std::pointer_traits<pointer>::pointer_to(*_M_local_buf);
250       }
251     public:
252       basic_string()
253       : _M_dataplus(_M_local_data())
254       { }
256     };
258     typedef basic_string<char> string;
261 //--- algorithm.h
262 #include "pair.h"
263 namespace std {
264     struct _Power2_rehash_policy
265   {
266     std::pair<bool, std::size_t>
267     _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt,
268      std::size_t __n_ins) noexcept
269     {
270         return { false, 0 };
271     }
272   };
275 //--- config.h
276 namespace std
278   typedef __SIZE_TYPE__         size_t;