aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2020-07-07 16:33:12 -0400
committerPatrick Palka <ppalka@redhat.com>2020-07-07 16:33:12 -0400
commit9845b7b45621e3833aee47276cb111e43be0e48b (patch)
treef8ff41d0207995a8ba934f42c552e8039214601e
parent7126583af5d29235584b51b3b05eeaba2adef024 (diff)
downloadgcc-9845b7b45621e3833aee47276cb111e43be0e48b.zip
gcc-9845b7b45621e3833aee47276cb111e43be0e48b.tar.gz
gcc-9845b7b45621e3833aee47276cb111e43be0e48b.tar.bz2
c++: wrong pretty printing of nested type [PR95303]
In the testcase below, we pretty print the nested type A<int>::B as A<int>::B<int> because we don't check whether B is itself a class template before printing the innermost set of template arguments from B's TEMPLATE_INFO (which in this case belong to A). This patch fixes this by checking PRIMARY_TEMPLATE_P beforehand. gcc/cp/ChangeLog: PR c++/95303 * cxx-pretty-print.c (pp_cxx_unqualified_id): Check PRIMARY_TEMPLATE_P before printing the innermost template arguments. gcc/testsuite/ChangeLog: PR c++/95303 * g++.dg/concepts/diagnostic14.C: New test.
-rw-r--r--gcc/cp/cxx-pretty-print.c13
-rw-r--r--gcc/testsuite/g++.dg/concepts/diagnostic14.C36
2 files changed, 43 insertions, 6 deletions
diff --git a/gcc/cp/cxx-pretty-print.c b/gcc/cp/cxx-pretty-print.c
index 188462a..263f225 100644
--- a/gcc/cp/cxx-pretty-print.c
+++ b/gcc/cp/cxx-pretty-print.c
@@ -173,12 +173,13 @@ pp_cxx_unqualified_id (cxx_pretty_printer *pp, tree t)
case UNBOUND_CLASS_TEMPLATE:
pp_cxx_unqualified_id (pp, TYPE_NAME (t));
if (tree ti = TYPE_TEMPLATE_INFO_MAYBE_ALIAS (t))
- {
- pp_cxx_begin_template_argument_list (pp);
- tree args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (ti));
- pp_cxx_template_argument_list (pp, args);
- pp_cxx_end_template_argument_list (pp);
- }
+ if (PRIMARY_TEMPLATE_P (TI_TEMPLATE (ti)))
+ {
+ pp_cxx_begin_template_argument_list (pp);
+ tree args = INNERMOST_TEMPLATE_ARGS (TI_ARGS (ti));
+ pp_cxx_template_argument_list (pp, args);
+ pp_cxx_end_template_argument_list (pp);
+ }
break;
case BIT_NOT_EXPR:
diff --git a/gcc/testsuite/g++.dg/concepts/diagnostic14.C b/gcc/testsuite/g++.dg/concepts/diagnostic14.C
new file mode 100644
index 0000000..ec2b68c
--- /dev/null
+++ b/gcc/testsuite/g++.dg/concepts/diagnostic14.C
@@ -0,0 +1,36 @@
+// PR c++/95303
+// { dg-do compile { target c++20 } }
+
+template<class>
+struct A {
+ struct B {};
+};
+
+template<class T>
+ requires __is_same(T, char)
+struct A<T> {
+ struct B {};
+};
+
+template<>
+ struct A<bool> {
+ struct B {};
+ };
+
+template<class T>
+concept C = requires (T&& t) { // { dg-message "\\\[with T = A<int>::B\\\]" }
+ t.a;
+};
+static_assert(C<A<int>::B>); // { dg-error "failed" }
+
+template<class T>
+concept D = requires (T&& t) { // { dg-message "\\\[with T = A<char>::B\\\]" }
+ t.a;
+};
+static_assert(D<A<char>::B>); // { dg-error "failed" }
+
+template<class T>
+concept E = requires (T&& t) { // { dg-message "\\\[with T = A<bool>::B\\\]" }
+ t.a;
+};
+static_assert(E<A<bool>::B>); // { dg-error "failed" }