diff mbox series

c++: Diagnose cv-qualified decltype(auto) [PR79815]

Message ID 20200709024816.1273734-1-polacek@redhat.com
State New
Headers show
Series c++: Diagnose cv-qualified decltype(auto) [PR79815] | expand

Commit Message

Marek Polacek July 9, 2020, 2:48 a.m. UTC
"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?

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


base-commit: 50873cc588fcc20384212b6dddca74393023a0e3

Comments

Jason Merrill July 14, 2020, 1:19 p.m. UTC | #1
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 mbox series

Patch

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" }