On 6/2/21 7:05 PM, Patrick Palka wrote:
On Wed, 2 Jun 2021, Jason Merrill wrote:
On 6/2/21 4:56 PM, Patrick Palka wrote:
On Wed, 2 Jun 2021, Patrick Palka wrote:
On Wed, 2 Jun 2021, Jason Merrill wrote:
On 6/2/21 2:39 PM, Patrick Palka wrote:
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.
Hmm, the patch looks fine, but why does the TYPE_DECL test fail for the
alias?
Ah, I hadn't considered investigating that. It seems make_typename_type
always returns a _TYPE instead of a TYPE_DECL when resolving a dependent
name that's a template-id, regardless of the tf_keep_type_decl flag.
This can be easily fixed like so, and this change alone is sufficient to
fix the PR (no changes to qualttp20.C needed). Note that this change
should only have an effect when tf_keep_type_decl is passed to
make_typename_type, and the only such caller is the TYPENAME_TYPE case
of tsubst in question, so this change seems pretty safe.
The downside is that we don't get the __restrict__-dropping
"improvement" as exhibited by qualttp20.C that the original patch
provides, so this other approach is more conservative in that sense.
So shall we go with the original patch, or something like the following?
(If we go with the original patch, it just occurred to me that we could
remove tf_keep_type_decl altogether.) Testing in progress.
For sake of concreteness, here's the full alternative patch for
consideration (modulo ChangeLog):
This seems better. I think the only non-type return from
lookup_template_class is error_mark_node; does it work to check that
specifically rather than !TYPE_P?
Indeed, checking for error_mark_node instead works nicely. Does the
following look OK? Bootstrapped and regtested on x86_64-pc-linux-gnu.
OK.
-- >8 --
Subject: [PATCH] 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 even in the case
of a dependent template-id name.
Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?
PR c++/100592
gcc/cp/ChangeLog:
* decl.c (make_typename_type): After dispatching to
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.
* g++.dg/template/qualttp20.C: Remove dg-error and augment.
---
gcc/cp/decl.c | 13 +++++++++----
gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C | 13 +++++++++++++
2 files changed, 22 insertions(+), 4 deletions(-)
create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C
diff --git a/gcc/cp/decl.c b/gcc/cp/decl.c
index fb21a3a1ae8..a3687dbb0dd 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 00000000000..6a61f93a0b0
--- /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&;