Whilst developing the location-wrapper patch kit, I accumulated various source files for which my work-in-progress patched-cc1plus had different behavior to an unpatched cc1plus: some of these were crashes, others were erroneous diagnostics.
All of these are now fixed, but it seems appropriate to capture them in our testsuite, hence this patch. Tested in conjunction with the patch kit; adds 12 PASS, 2 UNSUPPORTED and 3 XFAILs to g++.sum. The XFAILs are due to the use of dg-excess-errors in g++.dg/wrappers/cp-stdlib.C. This source file is full of syntax errors, but used to ICE my cc1plus *somewhere* in error recovery, and I wasn't able to minimize it further at the time. I fixed the ICE, but it seems worth keeping as a test case. I checked hacking in an ICE, and dg-excess-errors will FAIL on it (rather than merely XFAIL, on all of the syntax errors). OK for trunk? gcc/testsuite/ChangeLog: PR c++/43486 * g++.dg/wrappers: New subdirectory. * g++.dg/wrappers/README: New file. * g++.dg/wrappers/alloc.C: New test case. * g++.dg/wrappers/cow-istream-string.C: New test case. * g++.dg/wrappers/cp-stdlib.C: New test case. * g++.dg/wrappers/sanitizer_coverage_libcdep_new.C: New test case. * g++.dg/wrappers/wrapper-around-type-pack-expansion.C: New test case. --- gcc/testsuite/g++.dg/wrappers/README | 2 + gcc/testsuite/g++.dg/wrappers/alloc.C | 43 ++++++++ gcc/testsuite/g++.dg/wrappers/cow-istream-string.C | 15 +++ gcc/testsuite/g++.dg/wrappers/cp-stdlib.C | 117 +++++++++++++++++++++ .../wrappers/sanitizer_coverage_libcdep_new.C | 22 ++++ .../wrappers/wrapper-around-type-pack-expansion.C | 50 +++++++++ 6 files changed, 249 insertions(+) create mode 100644 gcc/testsuite/g++.dg/wrappers/README create mode 100644 gcc/testsuite/g++.dg/wrappers/alloc.C create mode 100644 gcc/testsuite/g++.dg/wrappers/cow-istream-string.C create mode 100644 gcc/testsuite/g++.dg/wrappers/cp-stdlib.C create mode 100644 gcc/testsuite/g++.dg/wrappers/sanitizer_coverage_libcdep_new.C create mode 100644 gcc/testsuite/g++.dg/wrappers/wrapper-around-type-pack-expansion.C diff --git a/gcc/testsuite/g++.dg/wrappers/README b/gcc/testsuite/g++.dg/wrappers/README new file mode 100644 index 0000000..9cba970 --- /dev/null +++ b/gcc/testsuite/g++.dg/wrappers/README @@ -0,0 +1,2 @@ +This directory contains reproducers for issues seen when adding location +wrapper nodes to the C++ frontend (ICEs and behavior changes). diff --git a/gcc/testsuite/g++.dg/wrappers/alloc.C b/gcc/testsuite/g++.dg/wrappers/alloc.C new file mode 100644 index 0000000..e004470 --- /dev/null +++ b/gcc/testsuite/g++.dg/wrappers/alloc.C @@ -0,0 +1,43 @@ +// { dg-do compile { target c++11 } } + +template<typename _Default, typename _AlwaysVoid, template<typename...> class _Op, typename... _Args> +struct __detector +{ + using type = _Op<_Args...>; +}; +template<typename _Default, template<typename...> class _Op, typename... _Args> +using __detected_or = __detector<_Default, void, _Op, _Args...>; +template<typename _Default, template<typename...> class _Op, typename... _Args> +using __detected_or_t = typename __detected_or<_Default, _Op, _Args...>::type; +template<typename _Alloc> +struct allocator_traits { + template<typename _Tp> + using __pointer = typename _Tp::pointer; + using pointer = __detected_or_t<typename _Alloc::value_type*, __pointer, _Alloc>; +}; +template<typename _Storage_policy> +struct _Pointer_adapter { + typedef typename _Storage_policy::element_type element_type; + typedef element_type& reference; +}; +template<typename _Tp> +inline _Tp* addressof(_Tp& __r); // { dg-warning "used but never defined" } +template<typename _Alloc> +struct __allocated_ptr { + __allocated_ptr() + { + using pointer = typename allocator_traits<_Alloc>::pointer; + typename _Pointer_adapter<pointer>::reference __r = *(int*)0; + addressof(__r); + } +}; +template<typename _Tp> +struct _Std_pointer_impl { + typedef _Tp element_type; +}; +template<typename Tp> +struct CustomPointerAlloc { + typedef Tp value_type; + typedef _Pointer_adapter<_Std_pointer_impl<Tp>> pointer; +}; +__allocated_ptr<CustomPointerAlloc<int>> __guard_ptr; diff --git a/gcc/testsuite/g++.dg/wrappers/cow-istream-string.C b/gcc/testsuite/g++.dg/wrappers/cow-istream-string.C new file mode 100644 index 0000000..23b0585 --- /dev/null +++ b/gcc/testsuite/g++.dg/wrappers/cow-istream-string.C @@ -0,0 +1,15 @@ +template<typename _CharT> +struct basic_string { + static const _CharT _S_terminal; + static void assign(const _CharT& __c2); + void _M_set_length_and_sharable() { + assign(_S_terminal); + } +}; + +template<typename _CharT> +const _CharT basic_string<_CharT>::_S_terminal = _CharT(); + +void getline(basic_string<char>& __str) { + __str._M_set_length_and_sharable(); +} diff --git a/gcc/testsuite/g++.dg/wrappers/cp-stdlib.C b/gcc/testsuite/g++.dg/wrappers/cp-stdlib.C new file mode 100644 index 0000000..d29585f --- /dev/null +++ b/gcc/testsuite/g++.dg/wrappers/cp-stdlib.C @@ -0,0 +1,117 @@ +/* At one time this triggered ICEs with location wrapper nodes, + apparently requiring error-recovery (hence the various syntax + errors in this file. */ + +// { dg-excess-errors "expected to be full of errors, but not an ICE" } + +namespace std +{ + inline namespace __cxx11 __attribute__((__abi_tag__ ("cxx11"))) { } +} +namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) +{ + template<typename _Tp> + class new_allocator + { + typedef _Tp value_type; + }; +} +namespace std +{ + template<typename _Tp> + using __allocator_base = __gnu_cxx::new_allocator<_Tp>; +} +namespace std __attribute__ ((__visibility__ ("default"))) +{ + { + }; + template<typename _Tp> + class allocator : public __allocator_base<_Tp> + { + }; + template<typename _Alloc> + struct allocator_traits : __allocator_traits_base + { + }; + template<typename _Tp> + struct allocator_traits<allocator<_Tp>> + { + using allocator_type = allocator<_Tp>; + template<typename _Up> + using rebind_alloc = allocator<_Up>; + allocate(allocator_type& __a, size_type __n) + }; +} +namespace __gnu_cxx __attribute__ ((__visibility__ ("default"))) +{ +template<typename _Alloc, typename = typename _Alloc::value_type> + struct __alloc_traits + : std::allocator_traits<_Alloc> + { + typedef std::allocator_traits<_Alloc> _Base_type; + template<typename _Tp> + struct rebind + { typedef typename _Base_type::template rebind_alloc<_Tp> other; }; + }; +{ + { + } + } + } + { + { + } +} +namespace std __attribute__ ((__visibility__ ("default"))) +{ + struct char_traits; +namespace __cxx11 { + template<typename _CharT, typename _Traits = char_traits<_CharT>, + typename _Alloc = allocator<_CharT> > + class basic_string; + } +} +namespace std __attribute__ ((__visibility__ ("default"))) +{ +namespace __cxx11 { + template<typename _CharT, typename _Traits, typename _Alloc> + class basic_string + { + typedef typename __gnu_cxx::__alloc_traits<_Alloc>::template + rebind<_CharT>::other _Char_alloc_type; + typedef __gnu_cxx::__alloc_traits<_Char_alloc_type> _Alloc_traits; + public: + { + { + } + } + operator=(const basic_string& __str) + { + { + { + { + const auto __len = __str.size(); + auto __alloc = __str._M_get_allocator(); + auto __ptr = _Alloc_traits::allocate(__alloc, __len + 1); + } + } + } + } + { + } + size() const noexcept + } +namespace filesystem +{ + class path + { + typedef char value_type; + typedef std::basic_string<value_type> string_type; + { + } + string_type _M_pathname; + }; + class directory_entry + { + void assign(const filesystem::path& __p) { _M_path = __p; } + filesystem::path _M_path; diff --git a/gcc/testsuite/g++.dg/wrappers/sanitizer_coverage_libcdep_new.C b/gcc/testsuite/g++.dg/wrappers/sanitizer_coverage_libcdep_new.C new file mode 100644 index 0000000..2be140b --- /dev/null +++ b/gcc/testsuite/g++.dg/wrappers/sanitizer_coverage_libcdep_new.C @@ -0,0 +1,22 @@ +namespace __sanitizer { + +enum FileAccessMode { + RdOnly, + WrOnly, + RdWr +}; + +int OpenFile(const char *filename, int mode, + int *errno_p); +} + +using namespace __sanitizer; + +namespace __sancov { + +static int OpenFile(const char* path) { + int err; + int fd = OpenFile(path, WrOnly, &err); + return fd; +} +} diff --git a/gcc/testsuite/g++.dg/wrappers/wrapper-around-type-pack-expansion.C b/gcc/testsuite/g++.dg/wrappers/wrapper-around-type-pack-expansion.C new file mode 100644 index 0000000..5072d1a --- /dev/null +++ b/gcc/testsuite/g++.dg/wrappers/wrapper-around-type-pack-expansion.C @@ -0,0 +1,50 @@ +// { dg-do compile { target c++11 } } + +typedef long unsigned int size_t; + +template<typename _Tp> +struct remove_reference {}; + +template<typename _Tp> +constexpr _Tp&& +forward(typename remove_reference<_Tp>::type& __t) noexcept +{ +} + +struct __allocator_traits_base { + template<typename _Tp, typename _Up, typename = void> + struct __rebind + { + using type = typename _Tp::template rebind<_Up>::other; + }; +}; + +template<typename _Alloc, typename _Up> +using __alloc_rebind = typename __allocator_traits_base::template __rebind<_Alloc, _Up>::type; + +template<typename _Alloc> struct allocator_traits { + template<typename _Tp> using rebind_alloc = __alloc_rebind<_Alloc, _Tp>; + template<typename _Tp, typename... _Args> + static auto construct(_Alloc& __a, _Tp* __p, _Args&&... __args) + -> decltype(_S_construct(__a, __p, forward<_Args>(__args)...)) { } +}; + +template<typename _Alloc, typename = typename _Alloc::value_type> +struct __alloc_traits : allocator_traits<_Alloc> { + typedef allocator_traits<_Alloc> _Base_type; + template<typename _Tp> struct rebind { typedef typename _Base_type::template rebind_alloc<_Tp> other; }; +}; + +template<typename _Tp> class allocator { + typedef _Tp value_type; + template<typename _Tp1> struct rebind { typedef allocator<_Tp1> other; }; +}; + +template<typename _CharT, typename _Alloc> +class basic_string { + typedef typename __alloc_traits<_Alloc>::template rebind<_CharT>::other _Char_alloc_type; +}; + +template<size_t _Nw> struct _Base_bitset { + static void foo (basic_string<char, allocator<char> >) {} +}; -- 1.8.5.3