PR c++/54875 - Error with alias template that resolves to an enum
authorDodji Seketeli <dodji@redhat.com>
Fri, 16 Nov 2012 15:20:03 +0000 (15:20 +0000)
committerDodji Seketeli <dodji@gcc.gnu.org>
Fri, 16 Nov 2012 15:20:03 +0000 (16:20 +0100)
commit26f2269fc4d1e4f97044db07b159f6d4eb4ab963
treee46d3166215d61ab370acfda67c709b799187321
parent2b723e217a034af37849bf2dae8fc0dba1c7f2ee
PR c++/54875 -  Error with alias template that resolves to an enum

Consider this short example:

     1 template<typename T>
     2 using AddConst = T const;
     3
     4 enum FwdEnum : int;
     5
     6 int main() {
     7   AddConst<FwdEnum> *ptr = nullptr;
     8 }

At line 7, when we build the type for AddConst<FwdEnum> in
lookup_template_class_1, the resulting type is the enum FwdEnum.  This
confuses lookup_template_class_1 near the if below, wrongly making it
taking the branch and thus calling tsubst_enum while it shouldn't:

      if (TREE_CODE (t) == ENUMERAL_TYPE && !is_dependent_type)
/* Now that the type has been registered on the instantiations
   list, we set up the enumerators.  Because the enumeration
   constants may involve the enumeration type itself, we make
   sure to register the type first, and then create the
   constants.  That way, doing tsubst_expr for the enumeration
   constants won't result in recursive calls here; we'll find
   the instantiation and exit above.  */
tsubst_enum (template_type, t, arglist);

Before the alias template feature, the only reason why TREE_CODE (t)
== ENUMERAL_TYPE would be true is when lookup_template_class_1 is
called for an enum that is a member of a class template.  But that
condition can be also true for an alias template instantiation.

So I guess that condition should be changed to TREE_CODE
(template_type) == ENUMERAL_TYPE, to specifically detect the member
enum of a class template case.  Note that for the alias template
instantiation case above, template_type points to a TEMPLATE_TYPE_PARM
which name is AddConst.

This is what the patchlet below does.

Bootstrapped and tested on x86_64-unknown-linux-gnu against trunk.

gcc/cp/

* pt.c (lookup_template_class_1): Look at the type of the
potential member enum of class template to determine if we are
actually substituting into a member enum of class template.

gcc/testsuite/

* g++.dg/cpp0x/alias-decl-27.C: New test.

From-SVN: r193562
gcc/cp/ChangeLog
gcc/cp/pt.c
gcc/testsuite/ChangeLog
gcc/testsuite/g++.dg/cpp0x/alias-decl-27.C [new file with mode: 0644]