[libcxx-commits] [PATCH] D60393: Force is_invocable template parameters to be complete types

Zoe Carver via Phabricator via libcxx-commits libcxx-commits at lists.llvm.org
Thu Apr 11 08:04:11 PDT 2019


zoecarver marked an inline comment as done.
zoecarver added inline comments.


================
Comment at: include/type_traits:4419
 
-  // FIXME: Check that _Ret, _Fp, and _Args... are all complete types, cv void,
-  // or incomplete array types as required by the standard.
----------------
EricWF wrote:
> zoecarver wrote:
> > This is now the only issue we still have to resolve. The standard says all these types must "be a complete type, (possibly cv-qualified) void, or an array of unknown bound. Otherwise, the behavior is undefined." Which (I think) means that we should either put an error/warning here or just let it be UB and get rid of the comment.
> We should keep the comment or replace it with a bug, but implementing the naive library implementation isn't what we want.
> 
> Also, it's worth noting checking for completeness doesn't address PR41360. `Foo*` is a complete type even if `Foo` isn't. For example, the return type, function type, and argument types are all complete in the following code:
> ```
> struct Base {};
> struct Derived;
> void sink(Base*);
> void test(Derived* p) { std::invoke(&sink, p); }
> struct Derived : Base {};
> ```
> 
> And there are many variations of this example, such as:
> 
> ```
> namespace NS { struct X; }
> void baz(...) = delete;
> void test2(const NS::X &x) { baz(x); }
> struct NS::X { friend void baz(const X&); };
> ```
> 
> Additionally, the current wording is grossly underconstrained.  It allows `invoke_result_t<Func, Incomplete&&>`, but forbids `invoke_result_t<Func, Incomplete>` even though they're functionally equivalent (`declval<T>()` and `declval<T&&>()` return the same type). 
> 
> Also the cost if instantiating all the templates required to check for completeness is non-trivial. 
> 
> Perhaps we should open a bug about this, file a standard issue, and see if we can add a builtin type-trait to clang which handles this checking for us.
> 
> Also, it's worth noting checking for completeness doesn't address PR41360. Foo* is a complete type even if Foo isn't. For example, the return type, function type, and argument types are all complete in the following code:

Do you mean that it should not be treated as a complete type or that it is not being treated as a complete type?

Anyway, I completely agree with your last point. How hard do you expect it would be to add a builtin? I have been looking for a relatively easy one to start with.


Repository:
  rCXX libc++

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60393/new/

https://reviews.llvm.org/D60393





More information about the libcxx-commits mailing list