c++: ahead-of-time overload set pruning for non-dep calls
authorPatrick Palka <ppalka@redhat.com>
Mon, 20 Dec 2021 14:28:20 +0000 (09:28 -0500)
committerPatrick Palka <ppalka@redhat.com>
Mon, 20 Dec 2021 14:28:20 +0000 (09:28 -0500)
commit2decd2cabe5a4f9f403cadc5470e5ed2095b0c45
tree2d59da32583f47810aeb52af89ca3fe75b1d09db
parent7424323bd5e1e27d8ffe37257459db5b28af18d2
c++: ahead-of-time overload set pruning for non-dep calls

This patch makes us remember the function selected by overload resolution
during ahead of time processing of a non-dependent call expression, so
that at instantiation time we avoid repeating some of the work of overload
resolution for the call.  Note that we already do this for non-dependent
operator expressions via build_min_non_dep_op_overload.

Some caveats:

 * When processing ahead of time a non-dependent call to a member
   function template of a currently open class template (as in
   g++.dg/template/deduce4.C), we end up generating an "inside-out"
   partial instantiation such as S<T>::foo<int, int>(), the likes of
   which we're apparently not prepared to fully instantiate.  So in this
   situation, we instead prune to the selected template instead of the
   specialization in this situation.

 * This change triggered a latent FUNCTION_DECL pretty printing issue
   in cpp0x/error2.C -- since we now resolve the call to foo<0> ahead
   of time, the error now looks like:

     error: expansion pattern ‘foo()()=0’ contains no parameter pack

   where the FUNCTION_DECL for foo<0> is clearly misprinted.  But this
   pretty-printing issue could be reproduced without this patch if
   we define foo as a non-template function.  Since this testcase was
   added to verify pretty printing of TEMPLATE_ID_EXPR, I work around
   this test failure by making the call to foo type-dependent and thus
   immune to this ahead of time pruning.

 * We now reject parts of cpp0x/fntmp-equiv1.C because we notice that
   the non-dependent call d(f, b) in

     int d(int, int);
     template <unsigned long f, unsigned b, typename> e<d(f, b)> d();

   is non-constexpr.  Since this testcase is about equivalency of
   dependent names in the context of declaration matching, it seems the
   best fix here is to make the calls to d, d2 and d3 within the
   function signatures dependent.

gcc/cp/ChangeLog:

* call.c (build_new_method_call): For a non-dependent call
expression inside a template, returning a templated tree
whose overload set contains just the selected function.
* semantics.c (finish_call_expr): Likewise.

gcc/testsuite/ChangeLog:

* g++.dg/cpp0x/error2.C: Make the call to foo type-dependent in
order to avoid latent pretty-printing issue for FUNCTION_DECL
inside MODOP_EXPR.
* g++.dg/cpp0x/fntmp-equiv1.C: Make the calls to d, d2 and d3
within the function signatures dependent.
* g++.dg/template/non-dependent16.C: New test.
* g++.dg/template/non-dependent16a.C: New test.
* g++.dg/template/non-dependent17.C: New test.
gcc/cp/call.c
gcc/cp/semantics.c
gcc/testsuite/g++.dg/cpp0x/error2.C
gcc/testsuite/g++.dg/cpp0x/fntmp-equiv1.C
gcc/testsuite/g++.dg/template/non-dependent16.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/non-dependent16a.C [new file with mode: 0644]
gcc/testsuite/g++.dg/template/non-dependent17.C [new file with mode: 0644]