281 lines · plain
1// Test case reduced from an experimental std modules implementation.2// Tests that the compiler don't emit confusing error about the ambiguous ctor3// about std::pair.4//5// RUN: rm -fr %t6// RUN: mkdir %t7// RUN: split-file %s %t8//9// RUN: %clang_cc1 -std=c++20 %t/string.cppm -I%t -emit-module-interface -o %t/std-string.pcm10// RUN: %clang_cc1 -std=c++20 %t/algorithm.cppm -I%t -emit-module-interface -o %t/std-algorithm.pcm11// RUN: %clang_cc1 -std=c++20 %t/Use.cppm -I%t -fprebuilt-module-path=%t -emit-module-interface -verify -o %t/Use.pcm12 13// Test again with reduced BMI.14// RUN: rm -fr %t15// RUN: mkdir %t16// RUN: split-file %s %t17//18// RUN: %clang_cc1 -std=c++20 %t/string.cppm -I%t -emit-reduced-module-interface -o %t/std-string.pcm19// RUN: %clang_cc1 -std=c++20 %t/algorithm.cppm -I%t -emit-reduced-module-interface -o %t/std-algorithm.pcm20// RUN: %clang_cc1 -std=c++20 %t/Use.cppm -I%t -fprebuilt-module-path=%t -emit-reduced-module-interface -verify -o %t/Use.pcm21 22//--- Use.cppm23// expected-no-diagnostics24module;25#include "config.h"26# 3 "pair-unambiguous-ctor.cppm" 1 327export module std:M;28# 3 "pair-unambiguous-ctor.cppm" 2 329import :string;30import :algorithm;31 32auto check() {33 return std::string();34}35 36//--- string.cppm37module;38#include "string.h"39# 28 "pair-unambiguous-ctor.cppm" 1 340export module std:string;41export namespace std {42 using std::string;43}44# 28 "pair-unambiguous-ctor.cppm" 2 345 46//--- algorithm.cppm47module;48#include "algorithm.h"49# 38 "pair-unambiguous-ctor.cppm" 1 350export module std:algorithm;51# 38 "pair-unambiguous-ctor.cppm" 2 352 53//--- pair.h54namespace std __attribute__ ((__visibility__ ("default")))55{ 56 typedef long unsigned int size_t;57 typedef long int ptrdiff_t;58 59 typedef decltype(nullptr) nullptr_t;60 61 template<typename _Tp, _Tp __v>62 struct integral_constant63 {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 };70 71 template<typename _Tp, _Tp __v>72 constexpr _Tp integral_constant<_Tp, __v>::value;73 74 typedef integral_constant<bool, true> true_type;75 typedef integral_constant<bool, false> false_type;76 77 template<bool __v>78 using __bool_constant = integral_constant<bool, __v>;79 80 81 template<bool, typename, typename>82 struct conditional;83 84 template<bool _Cond, typename _Iftrue, typename _Iffalse>85 struct conditional86 { typedef _Iftrue type; };87 88 template<typename _Iftrue, typename _Iffalse>89 struct conditional<false, _Iftrue, _Iffalse>90 { typedef _Iffalse type; };91 92 93 template<bool, typename _Tp = void>94 struct enable_if95 { };96 97 98 template<typename _Tp>99 struct enable_if<true, _Tp>100 { typedef _Tp type; };101 102 template<typename _Tp, typename... _Args>103 struct __is_constructible_impl104 : public __bool_constant<__is_constructible(_Tp, _Args...)>105 { };106 107 108 template<typename _Tp, typename... _Args>109 struct is_constructible110 : public __is_constructible_impl<_Tp, _Args...>111 {};112 113 template<typename>114 struct __is_void_helper115 : public false_type { };116 117 template<>118 struct __is_void_helper<void>119 : public true_type { };120 121 template<typename _Tp>122 struct is_void123 : public __is_void_helper<_Tp>::type124 { };125 126 template<typename...>127 class tuple;128 129 template<std::size_t...>130 struct _Index_tuple;131 132 template <bool, typename _T1, typename _T2>133 struct _PCC134 {135 template <typename _U1, typename _U2>136 static constexpr bool _ConstructiblePair()137 {138 return is_constructible<_T1, const _U1&>::value;139 }140 141 };142 143 template<typename _T1, typename _T2>144 struct pair145 {146 typedef _T1 first_type;147 typedef _T2 second_type;148 149 _T1 first;150 _T2 second;151 152 using _PCCP = _PCC<true, _T1, _T2>;153 154 template<typename _U1 = _T1, typename _U2=_T2, typename155 enable_if<_PCCP::template156 _ConstructiblePair<_U1, _U2>(),157 bool>::type=true>158 constexpr pair(const _T1& __a, const _T2& __b)159 : first(__a), second(__b) { }160 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 }170 171 private:172 template<typename... _Args1, std::size_t... _Indexes1,173 typename... _Args2, std::size_t... _Indexes2>174 constexpr175 pair(tuple<_Args1...>&, tuple<_Args2...>&,176 _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>);177 178 };179 180 template<typename _T1, typename _T2> pair(_T1, _T2) -> pair<_T1, _T2>;181}182 183//--- string.h184#include "pair.h"185 186namespace std __attribute__ ((__visibility__ ("default")))187{188 class __undefined;189 190 template<typename _Tp>191 using __make_not_void192 = typename conditional<is_void<_Tp>::value, __undefined, _Tp>::type;193 194 template <typename Ptr>195 struct pointer_traits {};196 197 template<typename _Tp>198 struct pointer_traits<_Tp*>199 {200 201 typedef _Tp* pointer;202 203 typedef _Tp element_type;204 205 static constexpr pointer206 pointer_to(__make_not_void<element_type>& __r) noexcept207 { return __builtin_addressof(__r); }208 };209 210 template<typename _Tp>211 class allocator;212 213 template<typename _Alloc>214 struct allocator_traits;215 216 template<typename _Tp>217 struct allocator_traits<allocator<_Tp>>218 {219 using pointer = _Tp*;220 };221 222 template<typename _Alloc>223 struct __alloc_traits224 : std::allocator_traits<_Alloc>225 {226 typedef std::allocator_traits<_Alloc> _Base_type;227 typedef typename _Base_type::pointer pointer;228 };229 230 template<class _CharT>231 struct char_traits;232 233 template<typename _CharT, typename _Traits = char_traits<_CharT>,234 typename _Alloc = allocator<_CharT> >235 class basic_string236 {237 typedef std::__alloc_traits<_Alloc> _Alloc_traits;238 239 public:240 typedef typename _Alloc_traits::pointer pointer;241 242 private:243 pointer _M_dataplus;244 _CharT _M_local_buf[16];245 246 pointer247 _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 { }255 256 };257 258 typedef basic_string<char> string;259}260 261//--- algorithm.h262#include "pair.h"263namespace std {264 struct _Power2_rehash_policy265 {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) noexcept269 {270 return { false, 0 };271 }272 };273}274 275//--- config.h276namespace std277{278 typedef __SIZE_TYPE__ size_t;279}280 281