Bug 100716 - member function template parameter should never be printed in candidate list and "T = T" should never be shown in substitutions
Summary: member function template parameter should never be printed in candidate list ...
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 12.0
: P3 normal
Target Milestone: 12.0
Assignee: Matthias Kretz (Vir)
URL:
Keywords: diagnostic
Depends on:
Blocks:
 
Reported: 2021-05-21 15:21 UTC by Matthias Kretz (Vir)
Modified: 2022-01-31 21:01 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments
proposed patch (1.80 KB, patch)
2021-05-27 06:04 UTC, Matthias Kretz (Vir)
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Matthias Kretz (Vir) 2021-05-21 15:21:37 UTC
template<typename T>
  struct A {
    template<typename U>
      void f() { }
  };

int main() {
  A<void>().f(0);
}

With -fpretty-templates this prints:

<source>: In function 'int main()':
<source>:8:6: error: no matching function for call to 'A<void>::f(int)'
<source>:4:12: note: candidate: 'template<class U> void A<T>::f() [with U = U; T = void]'
[...]

From the diagnostics, it is not apparent what entity U applies to. Also 'with U = U' is unnecessary noise. It should be:

<source>:4:12: note: candidate: 'template<class U> void A<T>::f<U>() [with T = void]'

However,

template<typename T>
  struct A {
    template<typename U>
      void f(U) { }
  };

int main() {
  A<void>().f();
}

doesn't need to show the function template parameter and should be diagnosed as:

<source>:4:12: note: candidate: 'template<class U> void A<T>::f(U) [with T = void]'

However, to distinguish the two cases, cp/error.c would need to determine whether the function template parameters are deducible. Alternatively, it would have to look at the list of function parameters and check whether all template parameters are used somehow (even if not deducible). Not sure whether that's worth the effort. I assume the current behavior was chosen because the majority of function template parameters are deducible?

FWIW, I believe the fix for PR50828 was incorrect since it removes the ability to control whether dump_template_parms called from dump_function_decl returns early for primary templates or not. I think the flags need to be modified for printing the function's scope, but not for dump_function_decl.

I'll try to come up with a patch.
Comment 1 Matthias Kretz (Vir) 2021-05-21 15:53:01 UTC
With -fno-pretty-templates both test cases do print the <U> template_parms. That's because in dump_function_decl, without flag_pretty_templates, t isn't generalized and thus is not considered a primary template. And dump_template_parms only returns early if primary is true.
Comment 2 Matthias Kretz (Vir) 2021-05-25 18:50:22 UTC
I'd like to revise my opinion above. dump_template_decl should never print the template parameter list of functions. I.e. it should be 'template<class U> f()' not 'template<class U> f<U>()'. Because it's also declared without the template parameter list, independent of whether the template parameter is deducible from the function arguments or not. That means the -fno-pretty-templates output needs to be fixed and the 'T = T' part needs to disappear.
Comment 3 Matthias Kretz (Vir) 2021-05-27 06:04:06 UTC
Created attachment 50877 [details]
proposed patch

Ensure dump_template_decl for function templates never prints template
parameters after the function name (it did with -fno-pretty-templates)
and skip output of irrelevant & confusing "[with T = T]" in
dump_substitution.

gcc/cp/ChangeLog:

        PR c++/100716
        * error.c (dump_template_bindings): Include code to print
        "[with" and ']', conditional on whether anything is printed at
        all. This is tied to whether a semicolon is needed to separate
        multiple template parameters. If the template argument repeats
        the template parameter (T = T), then skip the parameter.
        (dump_substitution): Moved code to print "[with" and ']' to
        dump_template_bindings.
        (dump_function_decl): Partial revert of PR50828, which masked
        TFF_TEMPLATE_NAME for all of dump_function_decl. Now
        TFF_TEMPLATE_NAME is masked for the scope of the function and
        only carries through to dump_function_name.
        (dump_function_name): Avoid calling dump_template_parms if
        TFF_TEMPLATE_NAME is set.

gcc/testsuite/ChangeLog:

        PR c++/100716
        * g++.dg/diagnostic/pr100716.C: New test.
        * g++.dg/diagnostic/pr100716-1.C: Same test with
        -fno-pretty-templates.
---
 gcc/cp/error.c                               | 59 +++++++++++++++-----
 gcc/testsuite/g++.dg/diagnostic/pr100716-1.C | 54 ++++++++++++++++++
 gcc/testsuite/g++.dg/diagnostic/pr100716.C   | 54 ++++++++++++++++++
 3 files changed, 152 insertions(+), 15 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/pr100716-1.C
 create mode 100644 gcc/testsuite/g++.dg/diagnostic/pr100716.C
Comment 4 GCC Commits 2021-05-27 21:01:22 UTC
The master branch has been updated by Jason Merrill <jason@gcc.gnu.org>:

https://gcc.gnu.org/g:c33ec196aa713c62d73907dc8f9e57d7ab2e4e4b

commit r12-1100-gc33ec196aa713c62d73907dc8f9e57d7ab2e4e4b
Author: Matthias Kretz <kretz@kde.org>
Date:   Thu May 27 17:25:37 2021 +0200

    c++: Output less irrelevant info for function template decl [PR100716]
    
    Ensure dump_template_decl for function templates never prints template
    parameters after the function name (it did with -fno-pretty-templates)
    and skip output of irrelevant & confusing "[with T = T]" in
    dump_substitution.
    
    gcc/cp/ChangeLog:
    
            PR c++/100716
            * error.c (dump_template_bindings): Include code to print
            "[with" and ']', conditional on whether anything is printed at
            all. This is tied to whether a semicolon is needed to separate
            multiple template parameters. If the template argument repeats
            the template parameter (T = T), then skip the parameter.
            (dump_substitution): Moved code to print "[with" and ']' to
            dump_template_bindings.
            (dump_function_decl): Partial revert of PR50828, which masked
            TFF_TEMPLATE_NAME for all of dump_function_decl. Now
            TFF_TEMPLATE_NAME is masked for the scope of the function and
            only carries through to dump_function_name.
            (dump_function_name): Avoid calling dump_template_parms if
            TFF_TEMPLATE_NAME is set.
    
    gcc/testsuite/ChangeLog:
    
            PR c++/100716
            * g++.dg/diagnostic/pr100716.C: New test.
            * g++.dg/diagnostic/pr100716-1.C: Same test with
            -fno-pretty-templates.
Comment 5 Matthias Kretz (Vir) 2021-07-22 08:28:31 UTC
Resolved by r12-1100-gc33ec196aa713c62d73907dc8f9e57d7ab2e4e4b. I don't think a backport should be done.