public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r11-9387] c++: CTAD within template argument [PR102933]
@ 2021-12-15 19:55 Patrick Palka
  0 siblings, 0 replies; only message in thread
From: Patrick Palka @ 2021-12-15 19:55 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:76c730cbf051281ff088ec18ee4f89fee4a8305a

commit r11-9387-g76c730cbf051281ff088ec18ee4f89fee4a8305a
Author: Patrick Palka <ppalka@redhat.com>
Date:   Thu Oct 28 10:46:46 2021 -0400

    c++: CTAD within template argument [PR102933]
    
    Here when checking for erroneous occurrences of 'auto' inside a template
    argument (which is allowed by the concepts TS for class templates),
    extract_autos_r picks up the CTAD placeholder for X{T{0}} which causes
    check_auto_in_tmpl_args to reject this valid template argument.  This
    patch fixes this by making extract_autos_r ignore CTAD placeholders.
    
    However, it seems we don't need to call check_auto_in_tmpl_args at all
    outside of the concepts TS since using 'auto' as a type-id is otherwise
    rejected more generally at parse time.  So this patch makes the function
    just exit early if !flag_concepts_ts.
    
    Similarly, I think the concepts code paths in do_auto_deduction and
    type_uses_auto are only necessary for the concepts TS, so this patch
    also restricts these code paths accordingly.
    
            PR c++/102933
    
    gcc/cp/ChangeLog:
    
            * parser.c (cp_parser_simple_type_specifier): Adjust diagnostic
            for using auto in parameter declaration.
            * pt.c (extract_autos_r): Ignore CTAD placeholders.
            (extract_autos): Use range-based for.
            (do_auto_deduction): Use extract_autos only for the concepts TS
            and not also for standard concepts.
            (type_uses_auto): Likewise with for_each_template_parm.
            (check_auto_in_tmpl_args): Just return false outside of the
            concepts TS.  Simplify.
    
    gcc/testsuite/ChangeLog:
    
            * g++.dg/cpp2a/nontype-class50.C: New test.
            * g++.dg/cpp2a/nontype-class50a.C: New test.
    
    (cherry picked from commit f70f17d03630fd948bc15a646ebe7e784125c4d4)

Diff:
---
 gcc/cp/parser.c                               |  2 +-
 gcc/cp/pt.c                                   | 24 +++++++++++++-----------
 gcc/testsuite/g++.dg/cpp2a/nontype-class50.C  | 13 +++++++++++++
 gcc/testsuite/g++.dg/cpp2a/nontype-class50a.C |  5 +++++
 4 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 030341640e9..6990a794af8 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -18766,7 +18766,7 @@ cp_parser_simple_type_specifier (cp_parser* parser,
 	  else if (!flag_concepts)
 	    pedwarn (token->location, 0,
 		     "use of %<auto%> in parameter declaration "
-		     "only available with %<-fconcepts-ts%>");
+		     "only available with %<-std=c++20%> or %<-fconcepts%>");
 	}
       else
 	type = make_auto ();
diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 6ff8d7840f8..d2b35da89a1 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -28345,7 +28345,7 @@ static int
 extract_autos_r (tree t, void *data)
 {
   hash_table<auto_hash> &hash = *(hash_table<auto_hash>*)data;
-  if (is_auto (t))
+  if (is_auto (t) && !template_placeholder_p (t))
     {
       /* All the autos were built with index 0; fix that up now.  */
       tree *p = hash.find_slot (t, INSERT);
@@ -28379,10 +28379,8 @@ extract_autos (tree type)
   for_each_template_parm (type, extract_autos_r, &hash, &visited, true);
 
   tree tree_vec = make_tree_vec (hash.elements());
-  for (hash_table<auto_hash>::iterator iter = hash.begin();
-       iter != hash.end(); ++iter)
+  for (tree elt : hash)
     {
-      tree elt = *iter;
       unsigned i = TEMPLATE_PARM_IDX (TEMPLATE_TYPE_PARM_INDEX (elt));
       TREE_VEC_ELT (tree_vec, i)
 	= build_tree_list (NULL_TREE, TYPE_NAME (elt));
@@ -29624,7 +29622,7 @@ do_auto_deduction (tree type, tree init, tree auto_node,
       tree parms = build_tree_list (NULL_TREE, type);
       tree tparms;
 
-      if (flag_concepts)
+      if (flag_concepts_ts)
 	tparms = extract_autos (type);
       else
 	{
@@ -29812,7 +29810,7 @@ type_uses_auto (tree type)
 {
   if (type == NULL_TREE)
     return NULL_TREE;
-  else if (flag_concepts)
+  else if (flag_concepts_ts)
     {
       /* The Concepts TS allows multiple autos in one type-specifier; just
 	 return the first one we find, do_auto_deduction will collect all of
@@ -29835,6 +29833,11 @@ type_uses_auto (tree type)
 bool
 check_auto_in_tmpl_args (tree tmpl, tree args)
 {
+  if (!flag_concepts_ts)
+    /* Only the concepts TS allows 'auto' as a type-id; it'd otherwise
+       have already been rejected by the parser more generally.  */
+    return false;
+
   /* If there were previous errors, nevermind.  */
   if (!args || TREE_CODE (args) != TREE_VEC)
     return false;
@@ -29844,11 +29847,10 @@ check_auto_in_tmpl_args (tree tmpl, tree args)
      We'll only be able to tell during template substitution, so we
      expect to be called again then.  If concepts are enabled and we
      know we have a type, we're ok.  */
-  if (flag_concepts
-      && (identifier_p (tmpl)
-	  || (DECL_P (tmpl)
-	      &&  (DECL_TYPE_TEMPLATE_P (tmpl)
-		   || DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl)))))
+  if (identifier_p (tmpl)
+      || (DECL_P (tmpl)
+	  &&  (DECL_TYPE_TEMPLATE_P (tmpl)
+	       || DECL_TEMPLATE_TEMPLATE_PARM_P (tmpl))))
     return false;
 
   /* Quickly search for any occurrences of auto; usually there won't
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class50.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class50.C
new file mode 100644
index 00000000000..1c2786a59e7
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class50.C
@@ -0,0 +1,13 @@
+// PR c++/102933
+// { dg-do compile { target c++20 } }
+
+template<class T> struct X { T t; };
+
+template<X> void f();
+
+template<class T>
+void g() {
+  f<X{T{0}}>();
+}
+
+template void g<int>();
diff --git a/gcc/testsuite/g++.dg/cpp2a/nontype-class50a.C b/gcc/testsuite/g++.dg/cpp2a/nontype-class50a.C
new file mode 100644
index 00000000000..eb8a6ad9375
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp2a/nontype-class50a.C
@@ -0,0 +1,5 @@
+// PR c++/102933
+// { dg-do compile { target c++20 } }
+// { dg-additional-options "-fconcepts-ts" }
+
+#include "nontype-class50.C"


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2021-12-15 19:55 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-12-15 19:55 [gcc r11-9387] c++: CTAD within template argument [PR102933] Patrick Palka

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).