Message ID | 20200417134036.1876657-1-ppalka@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: Abbreviated function template return type [PR92187] | expand |
On 4/17/20 9:40 AM, Patrick Palka wrote: > When updating an auto return type of an abbreviated function template in > splice_late_return_type, we should also propagate PLACEHOLDER_TYPE_CONSTRAINTS > (and cv-qualifiers) of the original auto node. > > Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK to commit? > > gcc/cp/ChangeLog: > > PR c++/92187 > * pt.c (splice_late_return_type): Propagate cv-qualifiers and > PLACEHOLDER_TYPE_CONSTRAINTS from the original auto node to the new one. > > gcc/testsuite/ChangeLog: > > PR c++/92187 > * g++.dg/concepts/abbrev5.C: New test. > * g++.dg/concepts/abbrev6.C: New test. > --- > gcc/cp/pt.c | 15 +++++++++++---- > gcc/testsuite/g++.dg/concepts/abbrev5.C | 15 +++++++++++++++ > gcc/testsuite/g++.dg/concepts/abbrev6.C | 12 ++++++++++++ > 3 files changed, 38 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/concepts/abbrev5.C > create mode 100644 gcc/testsuite/g++.dg/concepts/abbrev6.C > > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c > index 0a8ec3198d2..9e39f46a090 100644 > --- a/gcc/cp/pt.c > +++ b/gcc/cp/pt.c > @@ -29032,10 +29032,17 @@ splice_late_return_type (tree type, tree late_return_type) > { > tree idx = get_template_parm_index (*auto_node); > if (TEMPLATE_PARM_LEVEL (idx) <= processing_template_decl) > - /* In an abbreviated function template we didn't know we were dealing > - with a function template when we saw the auto return type, so update > - it to have the correct level. */ > - *auto_node = make_auto_1 (TYPE_IDENTIFIER (*auto_node), true); > + { > + /* In an abbreviated function template we didn't know we were dealing > + with a function template when we saw the auto return type, so update > + it to have the correct level. */ > + tree new_auto = make_auto_1 (TYPE_IDENTIFIER (*auto_node), false); > + PLACEHOLDER_TYPE_CONSTRAINTS (new_auto) > + = PLACEHOLDER_TYPE_CONSTRAINTS (*auto_node); I wonder about trying to share code between here and tsubst level lowering, but I guess this is short enough. OK > + TYPE_CANONICAL (new_auto) = canonical_type_parameter (new_auto); > + new_auto = cp_build_qualified_type (new_auto, TYPE_QUALS (*auto_node)); > + *auto_node = new_auto; > + } > } > return type; > } > diff --git a/gcc/testsuite/g++.dg/concepts/abbrev5.C b/gcc/testsuite/g++.dg/concepts/abbrev5.C > new file mode 100644 > index 00000000000..de594b5c1df > --- /dev/null > +++ b/gcc/testsuite/g++.dg/concepts/abbrev5.C > @@ -0,0 +1,15 @@ > +// PR c++/92187 > +// { dg-do compile { target concepts } } > + > +template <typename> > +concept C = false; > + > +C auto f(auto) > +{ > + return 42; // { dg-error "deduced return type" } > +} > + > +void foo() > +{ > + f(0); > +} > diff --git a/gcc/testsuite/g++.dg/concepts/abbrev6.C b/gcc/testsuite/g++.dg/concepts/abbrev6.C > new file mode 100644 > index 00000000000..862675e5193 > --- /dev/null > +++ b/gcc/testsuite/g++.dg/concepts/abbrev6.C > @@ -0,0 +1,12 @@ > +// { dg-do compile { target concepts } } > + > +const auto &f(auto) > +{ > + static int n; > + return n; > +} > + > +void foo() > +{ > + f(5) = 0; // { dg-error "read-only" } > +} >
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 0a8ec3198d2..9e39f46a090 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -29032,10 +29032,17 @@ splice_late_return_type (tree type, tree late_return_type) { tree idx = get_template_parm_index (*auto_node); if (TEMPLATE_PARM_LEVEL (idx) <= processing_template_decl) - /* In an abbreviated function template we didn't know we were dealing - with a function template when we saw the auto return type, so update - it to have the correct level. */ - *auto_node = make_auto_1 (TYPE_IDENTIFIER (*auto_node), true); + { + /* In an abbreviated function template we didn't know we were dealing + with a function template when we saw the auto return type, so update + it to have the correct level. */ + tree new_auto = make_auto_1 (TYPE_IDENTIFIER (*auto_node), false); + PLACEHOLDER_TYPE_CONSTRAINTS (new_auto) + = PLACEHOLDER_TYPE_CONSTRAINTS (*auto_node); + TYPE_CANONICAL (new_auto) = canonical_type_parameter (new_auto); + new_auto = cp_build_qualified_type (new_auto, TYPE_QUALS (*auto_node)); + *auto_node = new_auto; + } } return type; } diff --git a/gcc/testsuite/g++.dg/concepts/abbrev5.C b/gcc/testsuite/g++.dg/concepts/abbrev5.C new file mode 100644 index 00000000000..de594b5c1df --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/abbrev5.C @@ -0,0 +1,15 @@ +// PR c++/92187 +// { dg-do compile { target concepts } } + +template <typename> +concept C = false; + +C auto f(auto) +{ + return 42; // { dg-error "deduced return type" } +} + +void foo() +{ + f(0); +} diff --git a/gcc/testsuite/g++.dg/concepts/abbrev6.C b/gcc/testsuite/g++.dg/concepts/abbrev6.C new file mode 100644 index 00000000000..862675e5193 --- /dev/null +++ b/gcc/testsuite/g++.dg/concepts/abbrev6.C @@ -0,0 +1,12 @@ +// { dg-do compile { target concepts } } + +const auto &f(auto) +{ + static int n; + return n; +} + +void foo() +{ + f(5) = 0; // { dg-error "read-only" } +}