[Bug c++/12672] Evals template defaults args that it should not
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=12672 Patrick Palka changed: What|Removed |Added Target Milestone|--- |12.0 Resolution|--- |FIXED Status|ASSIGNED|RESOLVED --- Comment #16 from Patrick Palka --- Fixed for GCC 12 by accepting such code, which is permitted but not required by the standard.
[Bug c++/12672] Evals template defaults args that it should not
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=12672 --- Comment #15 from CVS Commits --- The master branch has been updated by Patrick Palka : https://gcc.gnu.org/g:f1e7319956928712e8bf4893ebdfeeb6441099ee commit r12-3271-gf1e7319956928712e8bf4893ebdfeeb6441099ee Author: Patrick Palka Date: Tue Aug 31 13:31:10 2021 -0400 c++: check arity before deduction w/ explicit targs [PR12672] During overload resolution, when the arity of a function template clearly disagrees with the arity of the call, no specialization of the function template could yield a viable candidate. The deduction routine type_unification_real already notices this situation, but not before it substitutes explicit template arguments into the template, a step which could induce a hard error. Although it's necessary to perform this substitution first in order to check arity perfectly (since the substitution can e.g. expand a non-trailing parameter pack), in most cases we can determine ahead of time whether there's an arity disagreement without needing to perform deduction at all. To that end, this patch implements an (approximate) arity check in add_template_candidate_real that guards actual deduction. It's enabled only when there are explicit template arguments since that's when deduction can force otherwise avoidable template instantiations. (I experimented with enabling it unconditionally as an optimization, and observed some improvements to compile time of about 5% but also some slowdowns of about the same magnitude, so kept it conditional.) In passing, this adds a least_p parameter to arity_rejection for sake of consistent diagnostics with unify_arity. A couple of testcases needed to be adjusted so that deduction continues to occur as intended after this change. Except in unify6.C, where we were expecting foo to be ill-formed due to substitution forming a function type with an added 'const', but ISTM this is permitted by [dcl.fct]/7, so I changed the test accordingly. PR c++/12672 gcc/cp/ChangeLog: * call.c (rejection_reason::call_varargs_p): Rename this previously unused member to ... (rejection_reason::least_p): ... this. (arity_rejection): Add least_p parameter. (add_template_candidate_real): When there are explicit template arguments, check that the arity of the call agrees with the arity of the function before attempting deduction. (print_arity_information): Add least_p parameter. (print_z_candidate): Adjust call to print_arity_information. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/decltype29.C: Adjust. * g++.dg/template/error56.C: Adjust. * g++.old-deja/g++.pt/unify6.C: Adjust. * g++.dg/template/explicit-args7.C: New test.
[Bug c++/12672] Evals template defaults args that it should not
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=12672 Patrick Palka changed: What|Removed |Added Status|NEW |ASSIGNED Assignee|unassigned at gcc dot gnu.org |ppalka at gcc dot gnu.org CC||ppalka at gcc dot gnu.org
[Bug c++/12672] Evals template defaults args that it should not
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=12672 Martin Sebor changed: What|Removed |Added CC||msebor at gcc dot gnu.org Known to fail||3.3, 4.5.3, 4.8.3, 4.9.3, ||5.3.0, 6.3.0, 7.0 --- Comment #14 from Martin Sebor --- With today's top of trunk (GCC 7) the error for the test case from comment #4 is still the same. Other compilers, including Clang 3.8, EDG 4.11, IBM XLC++, and Microsoft Visual Studio successfully compile the code.
[Bug c++/12672] Evals template defaults args that it should not
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=12672 --- Comment #10 from Jonathan Wakely --- (In reply to Ivan Godard from comment #0) > The problem seems to be that the compiler is not first pruning all > candidates with the wrong number of formals before doing type matching. Which is correct. The first thing it has to do is find the set of all the candidate functions, *then* it determines the subset which are viable functions ("those that have the proper number of arguments and meet certain other conditions"). 13.3.1 says: In each case where a candidate is a function template, candidate function template specializations are generated using template argument deduction (14.8.3, 14.8.2). Those candidates are then handled as candidate functions in the usual way.124 Footnote 124 says: 124) The process of argument deduction fully determines the parameter types of the function template specializations, i.e., the parameters of function template specializations contain no template parameter types. Therefore, except where specified otherwise, function template specializations and non-template functions (8.3.5) are treated equivalently for the remainder of overload resolution. So to find the candidate functions template argument deduction is done on each Foo, and that deduction results in an error outside the immediate context, where SFINAE doesn't apply.
[Bug c++/12672] Evals template defaults args that it should not
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=12672 --- Comment #7 from Jonathan Wakely --- EDG rejects the reduced examples in comments 3 and 4 (the original testcase doesn't compile any more for other reasons due to the preprocessed library headers).
[Bug c++/12672] Evals template defaults args that it should not
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=12672 --- Comment #9 from Jonathan Wakely --- This seems to be: http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1635 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#2008 might be related, and seems to agree with GCC.
[Bug c++/12672] Evals template defaults args that it should not
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=12672 Jonathan Wakely changed: What|Removed |Added Last reconfirmed|2009-04-16 16:42:54 |2016-1-15 --- Comment #8 from Jonathan Wakely --- (In reply to Wolfgang Bangerth from comment #4) > Confirmed. Here's something even shorter: > --- > template struct S { > typedef typename T::type type; > }; > > template::type> > struct A {}; > > template A Foo(T); > template void Foo(T, T); > > int main() { > Foo(1, 2); > } > > This fails to compile because the compiler tries to instantiate > the return type of the first Foo function. Whether that is actually > taken is irrelevant here, since we are only doing name lookup at this > stage, but we shouldn't error out: this is a SFINAE failure and > should just remove the first Foo function from the list of candidates. > It shouldn't be an error. I disagree, the error is not in the immediate context, so SFINAE doesn't apply. Clang does accept it though, maybe it doesn't instantiate the return type during name lookup? Not sure.
[Bug c++/12672] Evals template defaults args that it should not
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=12672 --- Comment #11 from Ivan Godard --- OP here; better late than never :-) IANALL, but the portions of the standard cited by Jonathan all refer to argument evaluation, while the problem here is in the result type. Why is the result even being considered before argument evaluation and identification is completed?
[Bug c++/12672] Evals template defaults args that it should not
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=12672 --- Comment #12 from Jonathan Wakely --- Template argument deduction requires substituting the template arguments where they appear. If that is in the return type, it gets substituted into the return type. If that causes a substitution error then deduction fails (that is how using enable_if on the return type works, it *must* consider the return type during argument deduction for that to work!). If it causes an error outside the immediate context you get an error, not deduction failure (14.8.2 p8).
[Bug c++/12672] Evals template defaults args that it should not
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=12672 --- Comment #13 from Jonathan Wakely --- (In reply to Ivan Godard from comment #11) > IANALL, but the portions of the standard cited by Jonathan all refer to > argument evaluation, Maybe you're confusing template arguments with function arguments? Template argument deduction is not limited to the function arguments.
[Bug c++/12672] Evals template defaults args that it should not
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=12672 --- Comment #6 from Ivan Godard --- Twelve years and counting? :-)
[Bug c++/12672] Evals template defaults args that it should not
--- Comment #5 from igodard at pacbell dot net 2009-04-16 17:02 --- Wow! Six years and counting! This might be my oldest outstanding bug. -- http://gcc.gnu.org/bugzilla/show_bug.cgi?id=12672