aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Palka <ppalka@redhat.com>2021-06-03 09:39:13 -0400
committerPatrick Palka <ppalka@redhat.com>2021-06-03 09:39:13 -0400
commitd999d9b7e53b9a9cd2004a19e84c637e5e5013f5 (patch)
tree2fa80535414e432aa07426d95410dc50a299af67
parent69f517ac20566a645ff41a9bfca535822205a538 (diff)
downloadgcc-d999d9b7e53b9a9cd2004a19e84c637e5e5013f5.zip
gcc-d999d9b7e53b9a9cd2004a19e84c637e5e5013f5.tar.gz
gcc-d999d9b7e53b9a9cd2004a19e84c637e5e5013f5.tar.bz2
c++: cv-qualified dependent name of alias tmpl [PR100592]
Here, the dependent template name in the return type of f() resolves to an alias of int& after substitution, and we end up complaining about qualifying this reference type with 'const' from cp_build_qualified_type rather than just silently dropping the qualification as per [dcl.ref]/1. The problem is ultimately that make_typename_type ignores the tf_keep_type_decl flag when the dependent name is a template-id. This in turn causes the TYPE_DECL check within tsubst <case TYPENAME_TYPE> to fail, and so we end up not passing tf_ignore_bad_quals to cp_build_qualified_type. This patch fixes this by making make_typename_type respect the tf_keep_type_decl flag in this situation. PR c++/100592 gcc/cp/ChangeLog: * decl.c (make_typename_type): After calling lookup_template_class, adjust the result to its TYPE_NAME and then consider the tf_keep_type_decl flag. gcc/testsuite/ChangeLog: * g++.dg/cpp0x/alias-decl-71.C: New test.
-rw-r--r--gcc/cp/decl.c13
-rw-r--r--gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C13
2 files changed, 22 insertions, 4 deletions
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index fb21a3a..a3687db 100644
--- a/gcc/cp/decl.c
+++ b/gcc/cp/decl.c
@@ -4136,10 +4136,15 @@ make_typename_type (tree context, tree name, enum tag_types tag_type,
return error_mark_node;
if (want_template)
- return lookup_template_class (t, TREE_OPERAND (fullname, 1),
- NULL_TREE, context,
- /*entering_scope=*/0,
- complain | tf_user);
+ {
+ t = lookup_template_class (t, TREE_OPERAND (fullname, 1),
+ NULL_TREE, context,
+ /*entering_scope=*/0,
+ complain | tf_user);
+ if (t == error_mark_node)
+ return error_mark_node;
+ t = TYPE_NAME (t);
+ }
if (DECL_ARTIFICIAL (t) || !(complain & tf_keep_type_decl))
t = TREE_TYPE (t);
diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C
new file mode 100644
index 0000000..6a61f93
--- /dev/null
+++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C
@@ -0,0 +1,13 @@
+// PR c++/100592
+// { dg-do compile { target c++11 } }
+
+template<bool>
+struct meta {
+ template<class> using if_c = int&;
+};
+
+template<bool B>
+typename meta<B>::template if_c<void> const f();
+
+using type = decltype(f<true>());
+using type = int&;