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.
This commit is contained in:
parent
50a2f53562
commit
43439d5e84
5 changed files with 35 additions and 14 deletions
|
@ -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
|
||||
|
|
|
@ -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");
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
16
gcc/testsuite/g++.dg/concepts/diagnostic12.C
Normal file
16
gcc/testsuite/g++.dg/concepts/diagnostic12.C
Normal file
|
@ -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" }
|
|
@ -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" }
|
||||
|
|
Loading…
Add table
Reference in a new issue