Patchwork C++ PATCH for c++/55058 (lost cv-quals with typedef in template)

login
register
mail settings
Submitter Jason Merrill
Date Dec. 6, 2012, 10:14 p.m.
Message ID <50C118AE.2060204@redhat.com>
Download mbox | patch
Permalink /patch/204328/
State New
Headers show

Comments

Jason Merrill - Dec. 6, 2012, 10:14 p.m.
When we look through a typedef, we need to keep any cv-quals that were 
added to it.

Tested x86_64-pc-linux-gnu, applying to 4.7 and trunk.
Paolo Carlini - Dec. 7, 2012, 9:33 a.m.
On 12/06/2012 11:14 PM, Jason Merrill wrote:
> When we look through a typedef, we need to keep any cv-quals that were 
> added to it.
Thanks! Patch fixes also c++/54975, but it didn't look (to me ;) as an 
obvious duplicate, thus before closing it, I'm also going to add the 
testcase.

Thanks again,
Paolo.

Patch

commit fb7279cb5a26b73256da2faa1f8078670531ef17
Author: Jason Merrill <jason@redhat.com>
Date:   Thu Dec 6 16:04:22 2012 -0500

    	PR c++/55058
    	* pt.c (tsubst): Keep the quals when looking through a typedef.

diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c
index 87cd337..33044e0 100644
--- a/gcc/cp/pt.c
+++ b/gcc/cp/pt.c
@@ -11013,8 +11013,13 @@  tsubst (tree t, tree args, tsubst_flags_t complain, tree in_decl)
 	  return r;
 	}
       else
-	/* We don't have an instantiation yet, so drop the typedef.  */
-	t = DECL_ORIGINAL_TYPE (decl);
+	{
+	  /* We don't have an instantiation yet, so drop the typedef.  */
+	  int quals = cp_type_quals (t);
+	  t = DECL_ORIGINAL_TYPE (decl);
+	  t = cp_build_qualified_type_real (t, quals,
+					    complain | tf_ignore_bad_quals);
+	}
     }
 
   if (type
diff --git a/gcc/testsuite/g++.dg/template/typedef40.C b/gcc/testsuite/g++.dg/template/typedef40.C
new file mode 100644
index 0000000..1d8be35
--- /dev/null
+++ b/gcc/testsuite/g++.dg/template/typedef40.C
@@ -0,0 +1,21 @@ 
+// PR c++/55058
+
+template <typename T>
+struct A { };
+
+template <typename T>
+struct B {
+  B(const A<T> T::* p);
+  typedef A<T> D;
+};
+
+template <typename T>
+B<T>::B(const D T::* p) { }
+
+struct C {
+  C() : e() {};
+
+  const A<C> e;
+};
+
+B<C> g(&C::e);