User account creation filtered due to spam.

Bug 58435 - Applying a type transformation to a list: const ignored
Summary: Applying a type transformation to a list: const ignored
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.8.1
: P3 normal
Target Milestone: 4.9.0
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-09-16 14:30 UTC by iavr
Modified: 2013-09-19 18:31 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2013-09-16 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description iavr 2013-09-16 14:30:34 UTC
The following applies a type transformation F to a list L of types T..., in particular for a transformation that adds "const":

------------------------------------------------------------------------

   template <template <typename...> class F, typename P> struct apply;

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

   template <typename T> using map = const T;
   template <typename> struct A { };
   template <typename> void dummy();

   int main() { dummy <apply <map, A <int> >::type>(); }

------------------------------------------------------------------------

It fails to link because of

   undefined reference to `void dummy<A<int> >()'

instead of the expected

  undefined reference to `void dummy<A<const int> >()'

i.e., "const" is ignored. It works for any other transformation I have tried.
Comment 1 Daniel Frey 2013-09-16 17:54:09 UTC
Note that it is triggered by the 'using', if you replace the mapping by

   template <typename T> struct map { typedef const T type; };

and adapt 'apply' like this:

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

the result changes to the expected:

  undefined reference to `void dummy<A<int const> >()'
Comment 2 Paolo Carlini 2013-09-16 18:27:22 UTC
Reduced:

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 <typename T> using map = const T;

static_assert(same<apply<map, int>::type, const int>::value, "");
Comment 3 Paolo Carlini 2013-09-16 19:28:59 UTC
Mine.
Comment 4 Paolo Carlini 2013-09-17 17:58:08 UTC
Fixed for 4.9.0.
Comment 5 paolo@gcc.gnu.org 2013-09-17 18:39:50 UTC
Author: paolo
Date: Tue Sep 17 17:46:03 2013
New Revision: 202662

URL: http://gcc.gnu.org/viewcvs?rev=202662&root=gcc&view=rev
Log:
/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.

Added:
    trunk/gcc/testsuite/g++.dg/cpp0x/alias-decl-38.C
Modified:
    trunk/gcc/cp/ChangeLog
    trunk/gcc/cp/pt.c
    trunk/gcc/testsuite/ChangeLog
Comment 6 iavr 2013-09-19 18:26:27 UTC
(In reply to paolo@gcc.gnu.org from comment #5)
> Author: paolo
> Date: Tue Sep 17 17:46:03 2013
> New Revision: 202662
> 

Hi,

Thanks a lot for your immediate response. However, I have to report that exactly the same problem occurs for "volatile" and "const volatile", as I just found out. Maybe these have been fixed as well already?

Yannis
Comment 7 Paolo Carlini 2013-09-19 18:31:05 UTC
Of course. Just look at the testcase.