aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/parser.c2
-rw-r--r--gcc/cp/pt.c24
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/nontype-class50.C13
-rw-r--r--gcc/testsuite/g++.dg/cpp2a/nontype-class50a.C5
4 files changed, 32 insertions, 12 deletions
diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c
index 93335c8..4c20757 100644
--- a/gcc/cp/parser.c
+++ b/gcc/cp/parser.c
@@ -19513,7 +19513,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 287cf4c..6604003 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -28560,7 +28560,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);
@@ -28594,10 +28594,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));
@@ -29837,7 +29835,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
{
@@ -30025,7 +30023,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
@@ -30048,6 +30046,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;
@@ -30057,11 +30060,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 0000000..1c2786a
--- /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 0000000..eb8a6ad
--- /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"