Hi,
I'm having a look to this PR filed by Daniel, which is again about
SFINAE for combined delete / new expressions, eg a simple example could
be (Daniel provided tens)
template<class T, class = decltype(::delete ::new T())>
auto g(int) -> char;
template<class>
auto g(...) -> char(&)[2];
static_assert(sizeof(g<void>(0)) == 2, "Ouch");
We handle incorrectly all such cases, all the static_assert for the
testcases provided by Daniel fire, for a simple reason: in
finish_decltype_type the check:
/* FIXME instantiation-dependent */
if (type_dependent_expression_p (expr)
/* In a template, a COMPONENT_REF has an IDENTIFIER_NODE for op1 even
if it isn't dependent, so that we can check access control at
instantiation time, so defer the decltype as well (PR 42277). */
|| (id_expression_or_member_access_p
&& processing_template_decl
&& TREE_CODE (expr) == COMPONENT_REF))
{
is false, thus we don't produce a DECLTYPE_TYPE and we don't tsubst into
it. Nothing can possibly work... Now I did the trivial experiment of
replacing the above with the usual:
if (processing_template_decl)
{
and *the whole* testsuite passes (all the tests provided by Daniel
included) with the only exception of nullptr26.C, ie:
template <class T, class U>
void f(T, U);
template <class T>
void f(T, decltype(nullptr));
int main()
{
f(1, nullptr);
}
which we reject as ambiguous (and of course it would be easy to handle
it specially, for sure std::nullptr_t it *is* special!).
Thus, I suspect the fix for this issue could turn out to be pretty
simple: any help?
In particular about the exact meaning of the FIXME? More generally, is
the issue here matter of compile-time optimization? Like we want to save
work when we actually *know* the type even in template context? (then
looks like type_dependent_expression_p isn't really what we want...)
Thanks!
Paolo.