aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2020-04-28 21:45:54 -0400
committerPatrick Palka <ppalka@redhat.com>2020-04-28 21:45:54 -0400
commit43439d5e8424f3a746003ef8953e1cdc120fbbd7 (patch)
tree04b68af12b869de33fd41fbfaaca1673ff5d275c /gcc
parent50a2f53562bfbf0cdc37be5d6fd7fd9e6271dba7 (diff)
downloadgcc-43439d5e8424f3a746003ef8953e1cdc120fbbd7.zip
gcc-43439d5e8424f3a746003ef8953e1cdc120fbbd7.tar.gz
gcc-43439d5e8424f3a746003ef8953e1cdc120fbbd7.tar.bz2
c++: Parameter pack in requires parameter list [PR94808]
When printing the substituted parameter list of a requires-expression as part of the "in requirements with ..." context line during concepts diagnostics, we weren't considering that substitution into a parameter pack can yield zero or multiple parameters. This patch changes the way we print the parameter list of a requires-expression in print_requires_expression_info. We now print the dependent form of the parameter list (along with its template parameter mapping) instead of printing its substituted form. Besides being an improvement in its own, this also sidesteps the substitution issue in the PR altogether. gcc/cp/ChangeLog: PR c++/94808 * error.c (print_requires_expression_info): Print the dependent form of the parameter list with its template parameter mapping, rather than printing the substituted form. gcc/testsuite/ChangeLog: PR c++/94808 * g++.dg/concepts/diagnostic12.C: New test. * g++.dg/concepts/diagnostic5.C: Adjust dg-message.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/cp/ChangeLog7
-rw-r--r--gcc/cp/error.c16
-rw-r--r--gcc/testsuite/ChangeLog6
-rw-r--r--gcc/testsuite/g++.dg/concepts/diagnostic12.C16
-rw-r--r--gcc/testsuite/g++.dg/concepts/diagnostic5.C4
5 files changed, 35 insertions, 14 deletions
diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog
index 8728389..c055801 100644
--- a/gcc/cp/ChangeLog
+++ b/gcc/cp/ChangeLog
@@ -1,3 +1,10 @@
+2020-04-29 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/94808
+ * error.c (print_requires_expression_info): Print the dependent
+ form of the parameter list with its template parameter mapping,
+ rather than printing the substituted form.
+
2020-04-28 Jason Merrill <jason@redhat.com>
PR c++/94583
diff --git a/gcc/cp/error.c b/gcc/cp/error.c
index 98c163d..46970f9 100644
--- a/gcc/cp/error.c
+++ b/gcc/cp/error.c
@@ -3746,7 +3746,6 @@ print_requires_expression_info (diagnostic_context *context, tree constr, tree a
map = tsubst_parameter_mapping (map, args, tf_none, NULL_TREE);
if (map == error_mark_node)
return;
- args = get_mapped_args (map);
print_location (context, cp_expr_loc_or_input_loc (expr));
pp_verbatim (context->printer, "in requirements ");
@@ -3756,19 +3755,12 @@ print_requires_expression_info (diagnostic_context *context, tree constr, tree a
pp_verbatim (context->printer, "with ");
while (parms)
{
- tree next = TREE_CHAIN (parms);
-
- TREE_CHAIN (parms) = NULL_TREE;
- cp_unevaluated u;
- tree p = tsubst (parms, args, tf_none, NULL_TREE);
- pp_verbatim (context->printer, "%q#D", p);
- TREE_CHAIN (parms) = next;
-
- if (next)
+ pp_verbatim (context->printer, "%q#D", parms);
+ if (TREE_CHAIN (parms))
pp_separate_with_comma ((cxx_pretty_printer *)context->printer);
-
- parms = next;
+ parms = TREE_CHAIN (parms);
}
+ pp_cxx_parameter_mapping ((cxx_pretty_printer *)context->printer, map);
pp_verbatim (context->printer, "\n");
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index d20308b..a824ba8 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,9 @@
+2020-04-29 Patrick Palka <ppalka@redhat.com>
+
+ PR c++/94808
+ * g++.dg/concepts/diagnostic12.C: New test.
+ * g++.dg/concepts/diagnostic5.C: Adjust dg-message.
+
2020-04-28 Alexandre Oliva <oliva@adacore.com>
PR target/94812
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic12.C b/gcc/testsuite/g++.dg/concepts/diagnostic12.C
new file mode 100644
index 0000000..a757342
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/diagnostic12.C
@@ -0,0 +1,16 @@
+// PR c++/94808
+// { dg-do compile { target concepts } }
+
+template<typename T, typename... Args>
+ concept c1 = requires (T t, Args... args) { *t; };
+// { dg-message "in requirements with .T t., .Args ... args. .with.* Args = \{\}" "" { target *-*-* } .-1 }
+
+static_assert(c1<int>); // { dg-error "failed" }
+
+void f(...);
+
+template<typename... Args>
+ concept c2 = requires (Args... args) { f(*args...); };
+// { dg-message "in requirements with .Args ... args. .with Args = \{int, char\}" "" { target *-*-* } .-1 }
+
+static_assert(c2<int, char>); // { dg-error "failed" }
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic5.C b/gcc/testsuite/g++.dg/concepts/diagnostic5.C
index 0d890d6..81705f6 100644
--- a/gcc/testsuite/g++.dg/concepts/diagnostic5.C
+++ b/gcc/testsuite/g++.dg/concepts/diagnostic5.C
@@ -9,7 +9,7 @@ template<typename T>
template<typename T>
concept c2 = requires (T x) { *x; };
// { dg-message "satisfaction of .c2<T>. .with T = char." "" { target *-*-* } .-1 }
-// { dg-message "in requirements with .char x." "" { target *-*-* } .-2 }
+// { dg-message "in requirements with .T x. .with T = char." "" { target *-*-* } .-2 }
// { dg-message "required expression .* is invalid" "" { target *-*-* } .-3 }
template<typename T>
@@ -25,7 +25,7 @@ template<typename T>
template<typename T>
concept c5 = requires (T x) { { &x } -> c1; };
// { dg-message "satisfaction of .c5<T>. .with T = char." "" { target *-*-* } .-1 }
-// { dg-message "in requirements with .char x." "" { target *-*-* } .-2 }
+// { dg-message "in requirements with .T x. .with T = char." "" { target *-*-* } .-2 }
template<typename T>
requires (c1<T> || c2<T>) || (c3<T> || c4<T>) || c5<T> // { dg-message "49: no operand" }