diff mbox series

c++: "'decltype_type' not supported" in diagnostic [PR85278]

Message ID 20200414154600.1280925-1-ppalka@redhat.com
State New
Headers show
Series c++: "'decltype_type' not supported" in diagnostic [PR85278] | expand

Commit Message

Patrick Palka April 14, 2020, 3:46 p.m. UTC
This fixes a garbled concepts diagnostic by moving the handling of DECLTYPE_TYPE
from pp_cxx_type_specifier_seq to cxx_pretty_printer::simple_type_specifier, a
move which also seems to be more consistent with the language grammar.

This patch also fixes pretty printing of rvalue reference types via
cxx_pretty_printer::type_id, which eventually calls pp_c_pointer which currently
doesn't distinguish between lvalue and rvalue references.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK to commit?

gcc/c-family/ChangeLog:

	PR c++/85278
	* c-pretty-print.c (pp_c_pointer) <case REFERENCE_TYPE>: Print a double
	ampersand if it's an rvalue reference type.

gcc/cp/ChangeLog:

	PR c++/85278
	* cxx-pretty-print.c (cxx_pretty_printer:simple_type_specifier)
	<case DECLTYPE_TYPE>: Handle DECLTYPE_TYPE here instead of ...
	(pp_cxx_type_specifier_seq) <case DECLTYPE_TYPE>: ... here.
	(cxx_pretty_printer::direct_abstract_declarator) <case DECLTYPE_TYPE>:
	New no-op case.

gcc/testsuite/ChangeLog:

	PR c++/85278
	* g++.dg/concepts/diagnostic9.C: New test.
---
 gcc/c-family/c-pretty-print.c               |  6 +++++-
 gcc/cp/cxx-pretty-print.c                   | 17 ++++++++++-------
 gcc/testsuite/g++.dg/concepts/diagnostic9.C | 11 +++++++++++
 3 files changed, 26 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/concepts/diagnostic9.C

Comments

Jason Merrill April 14, 2020, 5:57 p.m. UTC | #1
On 4/14/20 11:46 AM, Patrick Palka wrote:
> This fixes a garbled concepts diagnostic by moving the handling of DECLTYPE_TYPE
> from pp_cxx_type_specifier_seq to cxx_pretty_printer::simple_type_specifier, a
> move which also seems to be more consistent with the language grammar.
> 
> This patch also fixes pretty printing of rvalue reference types via
> cxx_pretty_printer::type_id, which eventually calls pp_c_pointer which currently
> doesn't distinguish between lvalue and rvalue references.
> 
> Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK to commit?

OK.

> gcc/c-family/ChangeLog:
> 
> 	PR c++/85278
> 	* c-pretty-print.c (pp_c_pointer) <case REFERENCE_TYPE>: Print a double
> 	ampersand if it's an rvalue reference type.
> 
> gcc/cp/ChangeLog:
> 
> 	PR c++/85278
> 	* cxx-pretty-print.c (cxx_pretty_printer:simple_type_specifier)
> 	<case DECLTYPE_TYPE>: Handle DECLTYPE_TYPE here instead of ...
> 	(pp_cxx_type_specifier_seq) <case DECLTYPE_TYPE>: ... here.
> 	(cxx_pretty_printer::direct_abstract_declarator) <case DECLTYPE_TYPE>:
> 	New no-op case.
> 
> gcc/testsuite/ChangeLog:
> 
> 	PR c++/85278
> 	* g++.dg/concepts/diagnostic9.C: New test.
> ---
>   gcc/c-family/c-pretty-print.c               |  6 +++++-
>   gcc/cp/cxx-pretty-print.c                   | 17 ++++++++++-------
>   gcc/testsuite/g++.dg/concepts/diagnostic9.C | 11 +++++++++++
>   3 files changed, 26 insertions(+), 8 deletions(-)
>   create mode 100644 gcc/testsuite/g++.dg/concepts/diagnostic9.C
> 
> diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
> index eccb63096fd..32f30f2d452 100644
> --- a/gcc/c-family/c-pretty-print.c
> +++ b/gcc/c-family/c-pretty-print.c
> @@ -278,7 +278,11 @@ pp_c_pointer (c_pretty_printer *pp, tree t)
>         if (TREE_CODE (t) == POINTER_TYPE)
>   	pp_c_star (pp);
>         else
> -	pp_c_ampersand (pp);
> +	{
> +	  pp_c_ampersand (pp);
> +	  if (TYPE_REF_IS_RVALUE (t))
> +	    pp_c_ampersand (pp);
> +	}
>         pp_c_type_qualifier_list (pp, t);
>         break;
>   
> diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
> index 840b5a8db8b..a26291eee0f 100644
> --- a/gcc/cp/cxx-pretty-print.c
> +++ b/gcc/cp/cxx-pretty-print.c
> @@ -1325,6 +1325,7 @@ cxx_pretty_printer::declaration_specifiers (tree t)
>   /* simple-type-specifier:
>         ::(opt) nested-name-specifier(opt) type-name
>         ::(opt) nested-name-specifier(opt) template(opt) template-id
> +      decltype-specifier
>         char
>         wchar_t
>         bool
> @@ -1363,6 +1364,13 @@ cxx_pretty_printer::simple_type_specifier (tree t)
>         pp_cxx_unqualified_id (this, TYPENAME_TYPE_FULLNAME (t));
>         break;
>   
> +    case DECLTYPE_TYPE:
> +      pp_cxx_ws_string (this, "decltype");
> +      pp_cxx_left_paren (this);
> +      this->expression (DECLTYPE_TYPE_EXPR (t));
> +      pp_cxx_right_paren (this);
> +      break;
> +
>       default:
>         c_pretty_printer::simple_type_specifier (t);
>         break;
> @@ -1389,6 +1397,7 @@ pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
>       case TEMPLATE_TEMPLATE_PARM:
>       case TYPE_DECL:
>       case BOUND_TEMPLATE_TEMPLATE_PARM:
> +    case DECLTYPE_TYPE:
>         pp_cxx_cv_qualifier_seq (pp, t);
>         pp->simple_type_specifier (t);
>         break;
> @@ -1399,13 +1408,6 @@ pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
>         pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
>         break;
>   
> -    case DECLTYPE_TYPE:
> -      pp_cxx_ws_string (pp, "decltype");
> -      pp_cxx_left_paren (pp);
> -      pp->expression (DECLTYPE_TYPE_EXPR (t));
> -      pp_cxx_right_paren (pp);
> -      break;
> -
>       case RECORD_TYPE:
>         if (TYPE_PTRMEMFUNC_P (t))
>   	{
> @@ -1799,6 +1801,7 @@ cxx_pretty_printer::direct_abstract_declarator (tree t)
>       case TEMPLATE_TEMPLATE_PARM:
>       case BOUND_TEMPLATE_TEMPLATE_PARM:
>       case UNBOUND_CLASS_TEMPLATE:
> +    case DECLTYPE_TYPE:
>         break;
>   
>       default:
> diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic9.C b/gcc/testsuite/g++.dg/concepts/diagnostic9.C
> new file mode 100644
> index 00000000000..b8f1fadd5e0
> --- /dev/null
> +++ b/gcc/testsuite/g++.dg/concepts/diagnostic9.C
> @@ -0,0 +1,11 @@
> +// PR c++/85278
> +// { dg-do compile { target concepts } }
> +
> +template<typename T>
> +void f2(T a)
> +  requires requires (const decltype(a) &&x) { -x; }
> +{ }
> +
> +int main() {
> +  f2<void*>(nullptr); // { dg-error "use of function .*const decltype\\(f2::a\\) *&&" }
> +}
>
diff mbox series

Patch

diff --git a/gcc/c-family/c-pretty-print.c b/gcc/c-family/c-pretty-print.c
index eccb63096fd..32f30f2d452 100644
--- a/gcc/c-family/c-pretty-print.c
+++ b/gcc/c-family/c-pretty-print.c
@@ -278,7 +278,11 @@  pp_c_pointer (c_pretty_printer *pp, tree t)
       if (TREE_CODE (t) == POINTER_TYPE)
 	pp_c_star (pp);
       else
-	pp_c_ampersand (pp);
+	{
+	  pp_c_ampersand (pp);
+	  if (TYPE_REF_IS_RVALUE (t))
+	    pp_c_ampersand (pp);
+	}
       pp_c_type_qualifier_list (pp, t);
       break;
 
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
index 840b5a8db8b..a26291eee0f 100644
--- a/gcc/cp/cxx-pretty-print.c
+++ b/gcc/cp/cxx-pretty-print.c
@@ -1325,6 +1325,7 @@  cxx_pretty_printer::declaration_specifiers (tree t)
 /* simple-type-specifier:
       ::(opt) nested-name-specifier(opt) type-name
       ::(opt) nested-name-specifier(opt) template(opt) template-id
+      decltype-specifier
       char
       wchar_t
       bool
@@ -1363,6 +1364,13 @@  cxx_pretty_printer::simple_type_specifier (tree t)
       pp_cxx_unqualified_id (this, TYPENAME_TYPE_FULLNAME (t));
       break;
 
+    case DECLTYPE_TYPE:
+      pp_cxx_ws_string (this, "decltype");
+      pp_cxx_left_paren (this);
+      this->expression (DECLTYPE_TYPE_EXPR (t));
+      pp_cxx_right_paren (this);
+      break;
+
     default:
       c_pretty_printer::simple_type_specifier (t);
       break;
@@ -1389,6 +1397,7 @@  pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
     case TEMPLATE_TEMPLATE_PARM:
     case TYPE_DECL:
     case BOUND_TEMPLATE_TEMPLATE_PARM:
+    case DECLTYPE_TYPE:
       pp_cxx_cv_qualifier_seq (pp, t);
       pp->simple_type_specifier (t);
       break;
@@ -1399,13 +1408,6 @@  pp_cxx_type_specifier_seq (cxx_pretty_printer *pp, tree t)
       pp_cxx_nested_name_specifier (pp, TYPE_METHOD_BASETYPE (t));
       break;
 
-    case DECLTYPE_TYPE:
-      pp_cxx_ws_string (pp, "decltype");
-      pp_cxx_left_paren (pp);
-      pp->expression (DECLTYPE_TYPE_EXPR (t));
-      pp_cxx_right_paren (pp);
-      break;
-
     case RECORD_TYPE:
       if (TYPE_PTRMEMFUNC_P (t))
 	{
@@ -1799,6 +1801,7 @@  cxx_pretty_printer::direct_abstract_declarator (tree t)
     case TEMPLATE_TEMPLATE_PARM:
     case BOUND_TEMPLATE_TEMPLATE_PARM:
     case UNBOUND_CLASS_TEMPLATE:
+    case DECLTYPE_TYPE:
       break;
 
     default:
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic9.C b/gcc/testsuite/g++.dg/concepts/diagnostic9.C
new file mode 100644
index 00000000000..b8f1fadd5e0
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/diagnostic9.C
@@ -0,0 +1,11 @@ 
+// PR c++/85278
+// { dg-do compile { target concepts } }
+
+template<typename T>
+void f2(T a)
+  requires requires (const decltype(a) &&x) { -x; }
+{ }
+
+int main() {
+  f2<void*>(nullptr); // { dg-error "use of function .*const decltype\\(f2::a\\) *&&" }
+}