From 1aaba40dcbe8fdc93d825d1f4e22edaa3e9aa5b1 Mon Sep 17 00:00:00 2001 From: Chuanqi Xu Date: Fri, 23 Sep 2022 15:17:35 +0800 Subject: [PATCH] [C++] [Modules] Add a test case for mocking implementation for std modules I found this with the patch: https://reviews.llvm.org/D131858. It breaks my local implementation but not the in-tree test cases. So I reduce the failure and submit the test case. The more testing should be always good. --- clang/test/Modules/pair-unambiguous-ctor.cppm | 265 ++++++++++++++++++++++++++ 1 file changed, 265 insertions(+) create mode 100644 clang/test/Modules/pair-unambiguous-ctor.cppm diff --git a/clang/test/Modules/pair-unambiguous-ctor.cppm b/clang/test/Modules/pair-unambiguous-ctor.cppm new file mode 100644 index 0000000..8022f34 --- /dev/null +++ b/clang/test/Modules/pair-unambiguous-ctor.cppm @@ -0,0 +1,265 @@ +// Test case reduced from an experimental std modules implementation. +// Tests that the compiler don't emit confusing error about the ambiguous ctor +// about std::pair. +// +// RUN: rm -fr %t +// RUN: mkdir %t +// RUN: split-file %s %t +// +// RUN: %clang_cc1 -std=c++20 %t/string.cppm -I%t -emit-module-interface -o %t/std-string.pcm +// RUN: %clang_cc1 -std=c++20 %t/algorithm.cppm -I%t -emit-module-interface -o %t/std-algorithm.pcm +// RUN: %clang_cc1 -std=c++20 %t/Use.cppm -I%t -fprebuilt-module-path=%t -emit-module-interface -verify -o %t/Use.pcm + +//--- Use.cppm +// expected-no-diagnostics +module; +#include "config.h" +export module std:M; +import :string; +import :algorithm; + +auto check() { + return std::string(); +} + +//--- string.cppm +module; +#include "string.h" +export module std:string; +export namespace std { + using std::string; +} + +//--- algorithm.cppm +module; +#include "algorithm.h" +export module std:algorithm; + +//--- pair.h +namespace std __attribute__ ((__visibility__ ("default"))) +{ + typedef long unsigned int size_t; + typedef long int ptrdiff_t; + + typedef decltype(nullptr) nullptr_t; + + template + struct integral_constant + { + static constexpr _Tp value = __v; + typedef _Tp value_type; + typedef integral_constant<_Tp, __v> type; + constexpr operator value_type() const noexcept { return value; } + constexpr value_type operator()() const noexcept { return value; } + }; + + template + constexpr _Tp integral_constant<_Tp, __v>::value; + + typedef integral_constant true_type; + typedef integral_constant false_type; + + template + using __bool_constant = integral_constant; + + + template + struct conditional; + + template + struct conditional + { typedef _Iftrue type; }; + + template + struct conditional + { typedef _Iffalse type; }; + + + template + struct enable_if + { }; + + + template + struct enable_if + { typedef _Tp type; }; + + template + struct __is_constructible_impl + : public __bool_constant<__is_constructible(_Tp, _Args...)> + { }; + + + template + struct is_constructible + : public __is_constructible_impl<_Tp, _Args...> + {}; + + template + struct __is_void_helper + : public false_type { }; + + template<> + struct __is_void_helper + : public true_type { }; + + template + struct is_void + : public __is_void_helper<_Tp>::type + { }; + + template + class tuple; + + template + struct _Index_tuple; + + template + struct _PCC + { + template + static constexpr bool _ConstructiblePair() + { + return is_constructible<_T1, const _U1&>::value; + } + + }; + + template + struct pair + { + typedef _T1 first_type; + typedef _T2 second_type; + + _T1 first; + _T2 second; + + using _PCCP = _PCC; + + template(), + bool>::type=true> + constexpr pair(const _T1& __a, const _T2& __b) + : first(__a), second(__b) { } + + constexpr pair& + operator=(typename conditional< + is_constructible<_T2>::value, + const pair&, nullptr_t>::type __p) + { + first = __p.first; + second = __p.second; + return *this; + } + + private: + template + constexpr + pair(tuple<_Args1...>&, tuple<_Args2...>&, + _Index_tuple<_Indexes1...>, _Index_tuple<_Indexes2...>); + + }; + + template pair(_T1, _T2) -> pair<_T1, _T2>; +} + +//--- string.h +#include "pair.h" + +namespace std __attribute__ ((__visibility__ ("default"))) +{ + class __undefined; + + template + using __make_not_void + = typename conditional::value, __undefined, _Tp>::type; + + template + struct pointer_traits {}; + + template + struct pointer_traits<_Tp*> + { + + typedef _Tp* pointer; + + typedef _Tp element_type; + + static constexpr pointer + pointer_to(__make_not_void& __r) noexcept + { return __builtin_addressof(__r); } + }; + + template + class allocator; + + template + struct allocator_traits; + + template + struct allocator_traits> + { + using pointer = _Tp*; + }; + + template + struct __alloc_traits + : std::allocator_traits<_Alloc> + { + typedef std::allocator_traits<_Alloc> _Base_type; + typedef typename _Base_type::pointer pointer; + }; + + template + struct char_traits; + + template, + typename _Alloc = allocator<_CharT> > + class basic_string + { + typedef std::__alloc_traits<_Alloc> _Alloc_traits; + + public: + typedef typename _Alloc_traits::pointer pointer; + + private: + pointer _M_dataplus; + _CharT _M_local_buf[16]; + + pointer + _M_local_data() + { + return std::pointer_traits::pointer_to(*_M_local_buf); + } + public: + basic_string() + : _M_dataplus(_M_local_data()) + { } + + }; + + typedef basic_string string; +} + +//--- algorithm.h +#include "pair.h" +namespace std { + struct _Power2_rehash_policy + { + std::pair + _M_need_rehash(std::size_t __n_bkt, std::size_t __n_elt, + std::size_t __n_ins) noexcept + { + return { false, 0 }; + } + }; +} + +//--- config.h +namespace std +{ + typedef __SIZE_TYPE__ size_t; +} + -- 2.7.4