Patchwork [C++] PR 58435

login
register
mail settings
Submitter Paolo Carlini
Date Sept. 17, 2013, 1:41 a.m.
Message ID <5237B33C.9080002@oracle.com>
Download mbox | patch
Permalink /patch/275349/
State New
Headers show

Comments

Paolo Carlini - Sept. 17, 2013, 1:41 a.m.
Hi,

for this kind of code:

template <template <typename> class F, typename T> struct apply
{ typedef F<T> type; };

template <typename T> using map = const T;

static_assert(std::is_same<apply<map, int>::type, const int>::value, "");

line #11542 of pt.c, in tsubst is reached:

         r = lookup_template_class (arg,
                        argvec, in_decl,
                        DECL_CONTEXT (arg),
                         /*entering_scope=*/0,
                        complain);
         return cp_build_qualified_type_real
           (r, cp_type_quals (t), complain);

for the 'typedef F<T> type;' with t, the typedef, which evidently has 
cp_type_quals (t) == 0, thus unqualified. The information about const T 
in the alias declaration is contained in r. Thus I believe we have 
simply to OR the two cp_type_quals, like we do in other cases. We also 
OR for case [TEMPLATE_TYPE_PARM] a few lines above.

Tested x86_64-linux.

Thanks!
Paolo.

////////////////////////
/cp
2013-09-17  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/58435
	* pt.c (tsubst, [BOUND_TEMPLATE_TEMPLATE_PARM]): Take into account
	the cp_type_quals (r) too.

/testsuite
2013-09-17  Paolo Carlini  <paolo.carlini@oracle.com>

	PR c++/58435
	* g++.dg/cpp0x/alias-decl-38.C: New.
Jason Merrill - Sept. 17, 2013, 12:48 p.m.
OK.

Jason

Patch

Index: cp/pt.c
===================================================================
--- cp/pt.c	(revision 202641)
+++ cp/pt.c	(working copy)
@@ -11540,7 +11540,7 @@  tsubst (tree t, tree args, tsubst_flags_t complain
 					    /*entering_scope=*/0,
 					   complain);
 		return cp_build_qualified_type_real
-		  (r, cp_type_quals (t), complain);
+		  (r, cp_type_quals (t) | cp_type_quals (r), complain);
 	      }
 	    else
 	      /* TEMPLATE_TEMPLATE_PARM or TEMPLATE_PARM_INDEX.  */
Index: testsuite/g++.dg/cpp0x/alias-decl-38.C
===================================================================
--- testsuite/g++.dg/cpp0x/alias-decl-38.C	(revision 0)
+++ testsuite/g++.dg/cpp0x/alias-decl-38.C	(working copy)
@@ -0,0 +1,41 @@ 
+// PR c++/58435
+// { dg-do compile { target c++11 } }
+
+template<typename T, typename U>
+struct same { static const bool value = false; };
+template<typename T>
+struct same<T, T> { static const bool value = true; };
+
+template <template <typename> class F, typename T> struct apply
+{ typedef F<T> type; };
+template <template <typename> class F, typename T> struct applyc
+{ typedef const F<T> type; };
+template <template <typename> class F, typename T> struct applyv
+{ typedef volatile F<T> type; };
+template <template <typename> class F, typename T> struct applycv
+{ typedef const volatile F<T> type; };
+
+template <typename T> using map = T;
+template <typename T> using mapc = const T;
+template <typename T> using mapv = volatile T;
+template <typename T> using mapcv = const volatile T;
+
+static_assert(same<apply<map, int>::type, int>::value, "");
+static_assert(same<apply<mapc, int>::type, const int>::value, "");
+static_assert(same<apply<mapv, int>::type, volatile int>::value, "");
+static_assert(same<apply<mapcv, int>::type, const volatile int>::value, "");
+
+static_assert(same<applyc<map, int>::type, const int>::value, "");
+static_assert(same<applyc<mapc, int>::type, const int>::value, "");
+static_assert(same<applyc<mapv, int>::type, const volatile int>::value, "");
+static_assert(same<applyc<mapcv, int>::type, const volatile int>::value, "");
+
+static_assert(same<applyv<map, int>::type, volatile int>::value, "");
+static_assert(same<applyv<mapc, int>::type, const volatile int>::value, "");
+static_assert(same<applyv<mapv, int>::type, volatile int>::value, "");
+static_assert(same<applyv<mapcv, int>::type, const volatile int>::value, "");
+
+static_assert(same<applycv<map, int>::type, const volatile int>::value, "");
+static_assert(same<applycv<mapc, int>::type, const volatile int>::value, "");
+static_assert(same<applycv<mapv, int>::type, const volatile int>::value, "");
+static_assert(same<applycv<mapcv, int>::type, const volatile int>::value, "");