]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
c++: ICE with auto in template arg [PR110065]
authorMarek Polacek <polacek@redhat.com>
Mon, 15 Jan 2024 14:15:59 +0000 (09:15 -0500)
committerMarek Polacek <polacek@redhat.com>
Mon, 15 Jan 2024 23:39:32 +0000 (18:39 -0500)
Here we started crashing with r14-1659 because that removed the
auto checking in cp_parser_template_type_arg which seemed like
dead code.  But the attached test shows that the code can still
be reached because cp_parser_type_id_1 checks auto only when
auto_is_implicit_function_template_parm_p is on.

Then I noticed that we're still crashing in C++20, and that ICE
started with r12-4772.  So I changed the reemerged check to use
flag_concepts_ts rather than flag_concepts on the basis that
check_auto_in_tmpl_args also checks flag_concepts_ts.

PR c++/110065

gcc/cp/ChangeLog:

* parser.cc (cp_parser_template_type_arg): Add auto checking.

gcc/testsuite/ChangeLog:

* g++.dg/concepts/auto8.C: New test.
* g++.dg/concepts/auto8a.C: New test.

gcc/cp/parser.cc
gcc/testsuite/g++.dg/concepts/auto8.C [new file with mode: 0644]
gcc/testsuite/g++.dg/concepts/auto8a.C [new file with mode: 0644]

index fd614ba3f31a7a44da96af2429ca5e783f4c9d71..c7ad3ecd3edf60ca01a55435e9b09784916dffbc 100644 (file)
@@ -25063,12 +25063,20 @@ cp_parser_type_id (cp_parser *parser, cp_parser_flags flags,
 static tree
 cp_parser_template_type_arg (cp_parser *parser)
 {
-  tree r;
   const char *saved_message = parser->type_definition_forbidden_message;
   parser->type_definition_forbidden_message
     = G_("types may not be defined in template arguments");
-  r = cp_parser_type_id_1 (parser, CP_PARSER_FLAGS_NONE, true, false, NULL);
+  tree r = cp_parser_type_id_1 (parser, CP_PARSER_FLAGS_NONE,
+                               /*is_template_arg=*/true,
+                               /*is_trailing_return=*/false, nullptr);
   parser->type_definition_forbidden_message = saved_message;
+  /* cp_parser_type_id_1 checks for auto, but only for
+     ->auto_is_implicit_function_template_parm_p.  */
+  if (cxx_dialect >= cxx14 && !flag_concepts_ts && type_uses_auto (r))
+    {
+      error ("invalid use of %<auto%> in template argument");
+      r = error_mark_node;
+    }
   return r;
 }
 
diff --git a/gcc/testsuite/g++.dg/concepts/auto8.C b/gcc/testsuite/g++.dg/concepts/auto8.C
new file mode 100644 (file)
index 0000000..f9d98b2
--- /dev/null
@@ -0,0 +1,17 @@
+// PR c++/110065
+// { dg-do compile { target c++17 } }
+
+template <typename>
+inline constexpr bool t = false;
+
+int
+f ()
+{
+  return t<auto(&)(const int*) -> auto&>; // { dg-error "template argument" }
+}
+
+void
+g ()
+{
+  t<auto(&)(const int*) -> auto&>; // { dg-error "template argument" }
+}
diff --git a/gcc/testsuite/g++.dg/concepts/auto8a.C b/gcc/testsuite/g++.dg/concepts/auto8a.C
new file mode 100644 (file)
index 0000000..fc60dc8
--- /dev/null
@@ -0,0 +1,18 @@
+// PR c++/110065
+// { dg-do compile { target c++17 } }
+// { dg-additional-options -fconcepts-ts }
+
+template <typename>
+inline constexpr bool t = false;
+
+int
+f ()
+{
+  return t<auto(&)(const int*) -> auto&>; // { dg-error "template argument" }
+}
+
+void
+g ()
+{
+  t<auto(&)(const int*) -> auto&>; // { dg-error "template argument" }
+}