From 430b731dd303f8be6ea222b0e1711e291fc48583 Mon Sep 17 00:00:00 2001
From: Andrew Sutton <asutton@lock3software.com>
Date: Thu, 17 Oct 2019 10:33:43 -0400
Subject: [PATCH 1/1] Fix a bug with type constraints in constructors.

gcc/cp/
	* parser.c (cp_parser_constructor_declarator_p): Pass an empty
	decl-specifier-seq to make sure we parse type constraints as part
	of a type-specifier.

gcc/testsuite/g++.dg/cpp2a
	* g++.dg/cpp2a/concepts5.C: New test.
---
 gcc/cp/ChangeLog                       |  6 ++++++
 gcc/cp/parser.c                        |  9 +++++++--
 gcc/testsuite/ChangeLog                |  4 ++++
 gcc/testsuite/g++.dg/cpp2a/concepts5.C | 24 ++++++++++++++++++++++++
 4 files changed, 41 insertions(+), 2 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp2a/concepts5.C

diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index ecaf312639b..d82032942c5 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,9 @@
+2019-10-15  Andrew Sutton  <asutton@lock3software.com>
+
+	* parser.c (cp_parser_constructor_declarator_p): Pass an empty
+	decl-specifier-seq to make sure we parse type constraints as part
+	of a type-specifier.
+
 2019-10-15  Nathan Sidwell  <nathan@acm.org>
 
 	* class.c (build_clones): Break out of clone_function_decl.  Just
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 53db8afc9f6..95248b8cc9d 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -28336,11 +28336,16 @@ cp_parser_constructor_declarator_p (cp_parser *parser, cp_parser_flags flags,
 	     looking for the type-specifier.  It is actually a function named
 	     `T::fn' that takes one parameter (of type `int') and returns a
 	     value of type `S'.  Constructors can be friends, but they must
-	     use a qualified name.  */
+	     use a qualified name.
+
+	     Parse with an empty set of declaration specifiers since we're
+	     trying to match a type-specifier of the first parameter.  */
+	  cp_decl_specifier_seq ctor_specs;
+	  clear_decl_specs (&ctor_specs);
 	  cp_parser_type_specifier (parser,
 				    (friend_p ? CP_PARSER_FLAGS_NONE
 				     : (flags & ~CP_PARSER_FLAGS_OPTIONAL)),
-				    /*decl_specs=*/NULL,
+				    /*decl_specs=*/&ctor_specs,
 				    /*is_declarator=*/true,
 				    /*declares_class_or_enum=*/NULL,
 				    /*is_cv_qualifier=*/NULL);
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b2b92deb134..02b9e124c18 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2019-10-15  Andrew Sutton  <asutton@lock3software.com>
+
+	* g++.dg/cpp2a/concepts5.C: New test.
+
 2019-10-16  Feng Xue  <fxue@os.amperecomputing.com>
 
 	PR ipa/91088
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts5.C b/gcc/testsuite/g++.dg/cpp2a/concepts5.C
new file mode 100644
index 00000000000..24ac2aa4095
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/concepts5.C
@@ -0,0 +1,24 @@
+// { dg-do compile { target c++2a } }
+
+
+template <typename T, typename U>
+concept same_as = __is_same_as(T, U);
+
+template<typename T>
+concept character = same_as<T, char>;
+
+struct T
+{
+  constexpr T(same_as<int> auto const x) : val(0) { }
+
+  constexpr T(character auto const x) : val(1) { }
+
+  int val;
+};
+
+void test()
+{
+  static_assert(T(0).val == 0);
+  static_assert(T('a').val == 1);
+}
+
-- 
2.18.0

