[PATCH] c++: cv-qualified dependent name of alias tmpl [PR100592]

Patrick Palka ppalka@redhat.com
Wed Jun 2 18:39:34 GMT 2021


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.

We already have the tf_ignore_bad_quals flag for this situation, but
the TYPENAME_TYPE branch of tsubst for some reason doesn't always use
this flag.  This patch just makes tsubst unconditionally use this flag
when substituting a TYPENAME_TYPE.

This change also causes us to drop bogus __restrict__ qualifiers more
consistently during substitution, as in qualttp20.C below where we no
longer diagnose the __restrict__ qualifier on B1<AS>::r.  Note that if
we artificially introduced a typedef as in B1<AS>::s we silently dropped
__restrict__ even before this patch, so this seems like an improvement.

Bootstrapped and regtested on x86_64-pc-linux-gnu, does this look OK for
trunk?

	PR c++/100592

gcc/cp/ChangeLog:

	* pt.c (tsubst) <case TYPENAME_TYPE>: Always pass
	tf_ignore_bad_quals to cp_build_qualified_type.

gcc/testsuite/ChangeLog:

	* g++.dg/cpp0x/alias-decl-71.C: New test.
	* g++.dg/template/qualttp20.C: Remove dg-error and augment.
---
 gcc/cp/pt.c                                | 10 ++++------
 gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C | 13 +++++++++++++
 gcc/testsuite/g++.dg/template/qualttp20.C  |  6 ++++--
 3 files changed, 21 insertions(+), 8 deletions(-)
 create mode 100644 gcc/testsuite/g++.dg/cpp0x/alias-decl-71.C

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 86259e900e9..2da5407a2a7 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -16066,10 +16066,7 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	if (f == error_mark_node)
 	  return f;
 	if (TREE_CODE (f) == TYPE_DECL)
-	  {
-	    complain |= tf_ignore_bad_quals;
-	    f = TREE_TYPE (f);
-	  }
+	  f = TREE_TYPE (f);
 
 	if (TREE_CODE (f) != TYPENAME_TYPE)
 	  {
@@ -16091,8 +16088,9 @@ tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	      }
 	  }
 
-	return cp_build_qualified_type_real
-	  (f, cp_type_quals (f) | cp_type_quals (t), complain);
+	int quals = cp_type_quals (f) | cp_type_quals (t);
+	complain |= tf_ignore_bad_quals;
+	return cp_build_qualified_type_real (f, quals, complain);
       }
 
     case UNBOUND_CLASS_TEMPLATE:
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&;
diff --git a/gcc/testsuite/g++.dg/template/qualttp20.C b/gcc/testsuite/g++.dg/template/qualttp20.C
index 52989bae538..3281f5d9eab 100644
--- a/gcc/testsuite/g++.dg/template/qualttp20.C
+++ b/gcc/testsuite/g++.dg/template/qualttp20.C
@@ -10,13 +10,15 @@ struct AS
 {
   typedef void (myT) ();
   struct L {};
+  typedef struct {} M;
   
 };
 
 
 template <typename T> struct B1 : T
 {
-  typedef typename T::L __restrict__ r;// { dg-error "'__restrict__' qualifiers cannot" }
+  typedef typename T::L __restrict__ r;
+  typedef typename T::M __restrict__ s;
   typedef typename T::myT __restrict__ p;
 
   // The following are DR 295 dependent
@@ -32,5 +34,5 @@ template <typename T> struct B2 : T
   myconst b;
 };
 
-B1<AS> b1;	// { dg-message "required" }
+B1<AS> b1;
 B2<AS> b2;
-- 
2.32.0.rc2



More information about the Gcc-patches mailing list