Fix a bug with type constraints in constructors.
authorAndrew Sutton <asutton@lock3software.com>
Wed, 23 Oct 2019 13:05:32 +0000 (13:05 +0000)
committerAndrew Sutton <asutton@gcc.gnu.org>
Wed, 23 Oct 2019 13:05:32 +0000 (13:05 +0000)
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/concepts5.C: New test.

From-SVN: r277323

gcc/cp/ChangeLog
gcc/cp/parser.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp2a/concepts5.C [new file with mode: 0644]

index 4295b0c..d151812 100644 (file)
        * decl.c (cxx_maybe_build_cleanup): When clearing location of cleanup,
        if cleanup is a nop, clear location of its operand too.
 
+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
index 6433f87..c597adb 100644 (file)
@@ -28336,11 +28336,19 @@ 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 decl-specifier-seq of the first parameter.  
+            This must be non-null so that cp_parser_simple_type_specifier
+            will recognize a constrained placeholder type such as:
+            'C<int> auto' where C is a type concept.  */
+         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);
index a9c4413..2fd237b 100644 (file)
        * gcc.dg/ipa/pr91089.c: Add sub-test for range analysis.
        * g++.dg/tree-ssa/ivopts-3.C: Force a function to be noinline.
 
+2019-10-15  Andrew Sutton  <asutton@lock3software.com>
+
+       * g++.dg/cpp2a/concepts5.C: New test.
+
 2019-10-15  Andrew Pinski  <apinski@marvell.com>
 
        * gcc.c-torture/compile/20191015-1.c: New test.
diff --git a/gcc/testsuite/g++.dg/cpp2a/concepts5.C b/gcc/testsuite/g++.dg/cpp2a/concepts5.C
new file mode 100644 (file)
index 0000000..24ac2aa
--- /dev/null
@@ -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);
+}
+