Message ID | 20200709024816.1273734-1-polacek@redhat.com |
---|---|
State | New |
Headers | show |
Series | c++: Diagnose cv-qualified decltype(auto) [PR79815] | expand |
On 7/8/20 10:48 PM, Marek Polacek wrote: > "If the placeholder is the decltype(auto) type-specifier, T shall be the > placeholder alone." but we weren't detecting "const decltype(auto)". > > I've just expanded the existing diagnostic detecting "decltype(auto) &" > and similar. > > Bootstrapped/regtested on x86_64-pc-linux-gnu, ok for trunk? OK. > gcc/cp/ChangeLog: > > PR c++/79815 > * decl.c (grokdeclarator): Detect cv-qual decltype(auto). > * pt.c (do_auto_deduction): Likewise. > > gcc/testsuite/ChangeLog: > > PR c++/79815 > * g++.dg/cpp1y/auto-fn58.C: New test. > --- > gcc/cp/decl.c | 17 +++++++++++++---- > gcc/cp/pt.c | 6 ++++++ > gcc/testsuite/g++.dg/cpp1y/auto-fn58.C | 8 ++++++++ > 3 files changed, 27 insertions(+), 4 deletions(-) > create mode 100644 gcc/testsuite/g++.dg/cpp1y/auto-fn58.C > > diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c > index 60a09e9497a..839ea8059e7 100644 > --- a/gcc/cp/decl.c > +++ b/gcc/cp/decl.c > @@ -12251,11 +12251,20 @@ grokdeclarator (const cp_declarator *declarator, > /* Only plain decltype(auto) is allowed. */ > if (tree a = type_uses_auto (type)) > { > - if (AUTO_IS_DECLTYPE (a) && a != type) > + if (AUTO_IS_DECLTYPE (a)) > { > - error_at (typespec_loc, "%qT as type rather than " > - "plain %<decltype(auto)%>", type); > - return error_mark_node; > + if (a != type) > + { > + error_at (typespec_loc, "%qT as type rather than " > + "plain %<decltype(auto)%>", type); > + return error_mark_node; > + } > + else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED) > + { > + error_at (typespec_loc, "%<decltype(auto)%> cannot be " > + "cv-qualified"); > + return error_mark_node; > + } > } > } > > diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c > index b6423f7432b..33d194e9e15 100644 > --- a/gcc/cp/pt.c > +++ b/gcc/cp/pt.c > @@ -28993,6 +28993,12 @@ do_auto_deduction (tree type, tree init, tree auto_node, > error ("%qT as type rather than plain %<decltype(auto)%>", type); > return error_mark_node; > } > + else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED) > + { > + if (complain & tf_error) > + error ("%<decltype(auto)%> cannot be cv-qualified"); > + return error_mark_node; > + } > } > else > { > diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn58.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn58.C > new file mode 100644 > index 00000000000..8f6ec9b79ab > --- /dev/null > +++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn58.C > @@ -0,0 +1,8 @@ > +// PR c++/79815 > +// { dg-do compile { target c++14 } } > + > +decltype(auto) const x = 1; // { dg-error "cannot be cv-qualified" } > +volatile decltype(auto) x2 = 1; // { dg-error "cannot be cv-qualified" } > +const volatile decltype(auto) x3 = 1; // { dg-error "cannot be cv-qualified" } > +const decltype(auto) fn() { return 42; } // { dg-error "cannot be cv-qualified" } > +const decltype(auto) fn2(); // { dg-error "cannot be cv-qualified" } > > base-commit: 50873cc588fcc20384212b6dddca74393023a0e3 >
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c index 60a09e9497a..839ea8059e7 100644 --- a/gcc/cp/decl.c +++ b/gcc/cp/decl.c @@ -12251,11 +12251,20 @@ grokdeclarator (const cp_declarator *declarator, /* Only plain decltype(auto) is allowed. */ if (tree a = type_uses_auto (type)) { - if (AUTO_IS_DECLTYPE (a) && a != type) + if (AUTO_IS_DECLTYPE (a)) { - error_at (typespec_loc, "%qT as type rather than " - "plain %<decltype(auto)%>", type); - return error_mark_node; + if (a != type) + { + error_at (typespec_loc, "%qT as type rather than " + "plain %<decltype(auto)%>", type); + return error_mark_node; + } + else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED) + { + error_at (typespec_loc, "%<decltype(auto)%> cannot be " + "cv-qualified"); + return error_mark_node; + } } } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index b6423f7432b..33d194e9e15 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -28993,6 +28993,12 @@ do_auto_deduction (tree type, tree init, tree auto_node, error ("%qT as type rather than plain %<decltype(auto)%>", type); return error_mark_node; } + else if (TYPE_QUALS (type) != TYPE_UNQUALIFIED) + { + if (complain & tf_error) + error ("%<decltype(auto)%> cannot be cv-qualified"); + return error_mark_node; + } } else { diff --git a/gcc/testsuite/g++.dg/cpp1y/auto-fn58.C b/gcc/testsuite/g++.dg/cpp1y/auto-fn58.C new file mode 100644 index 00000000000..8f6ec9b79ab --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp1y/auto-fn58.C @@ -0,0 +1,8 @@ +// PR c++/79815 +// { dg-do compile { target c++14 } } + +decltype(auto) const x = 1; // { dg-error "cannot be cv-qualified" } +volatile decltype(auto) x2 = 1; // { dg-error "cannot be cv-qualified" } +const volatile decltype(auto) x3 = 1; // { dg-error "cannot be cv-qualified" } +const decltype(auto) fn() { return 42; } // { dg-error "cannot be cv-qualified" } +const decltype(auto) fn2(); // { dg-error "cannot be cv-qualified" }