[libcxx-commits] [libcxx] 40a6be4 - [libc++] Ensure valid view for view_interface template parameter

Joe Loser via libcxx-commits libcxx-commits at lists.llvm.org
Fri Oct 29 16:12:45 PDT 2021


Author: Joe Loser
Date: 2021-10-29T19:04:54-04:00
New Revision: 40a6be4346097c008998d702381b07acbc6c9ae2

URL: https://github.com/llvm/llvm-project/commit/40a6be4346097c008998d702381b07acbc6c9ae2
DIFF: https://github.com/llvm/llvm-project/commit/40a6be4346097c008998d702381b07acbc6c9ae2.diff

LOG: [libc++] Ensure valid view for view_interface template parameter

Some types that inherit from `view_interface` do not meet the
preconditions. This came up during discussion
in https://reviews.llvm.org/D112631. Currently, the behavior is IFNDR,
but the preconditions can be easily checked, so let's do so.

In particular, we know each public member function calls the
`__derived()` private function, so we can do the check there. We
intentionally do it as a `static_assert` instead of a `requires` clause
to avoid hard erroring in some cases, such as with incomplete types. An
example hard error is:

```
llvm-project/build/include/c++/v1/__ranges/view_interface.h:48:14: note: because 'sizeof(_Tp)' would be invalid: invalid application of 'sizeof' to an incomplete type 'MoveOnlyForwardRange'
  requires { sizeof(_Tp); } &&
             ^
llvm-project/build/include/c++/v1/__ranges/view_interface.h:73:26: error: no matching member function for call to '__derived'
    return ranges::begin(__derived()) == ranges::end(__derived());
                         ^~~~~~~~~
llvm-project/libcxx/test/std/ranges/range.utility/view.interface/view.interface.pass.cpp:187:31: note: in instantiation of function template specialization 'std::ranges::view_interface<MoveOnlyForwardRange>::empty<Mov
eOnlyForwardRange>' requested here
  assert(!std::move(moveOnly).empty());
```

Reviewed By: Quuxplusone, Mordante, #libc

Differential Revision: https://reviews.llvm.org/D112665

Added: 
    

Modified: 
    libcxx/include/__ranges/view_interface.h

Removed: 
    


################################################################################
diff  --git a/libcxx/include/__ranges/view_interface.h b/libcxx/include/__ranges/view_interface.h
index 1c66dadfa1ea..8a1f5d8c9251 100644
--- a/libcxx/include/__ranges/view_interface.h
+++ b/libcxx/include/__ranges/view_interface.h
@@ -43,11 +43,13 @@ template<class _Derived>
 class view_interface : public view_base {
   _LIBCPP_HIDE_FROM_ABI
   constexpr _Derived& __derived() noexcept {
+    static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>);
     return static_cast<_Derived&>(*this);
   }
 
   _LIBCPP_HIDE_FROM_ABI
   constexpr _Derived const& __derived() const noexcept {
+    static_assert(sizeof(_Derived) && derived_from<_Derived, view_interface> && view<_Derived>);
     return static_cast<_Derived const&>(*this);
   }
 


        


More information about the libcxx-commits mailing list