http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54875



--- Comment #4 from Dodji Seketeli <dodji at gcc dot gnu.org> 2012-11-16 
15:20:11 UTC ---

Author: dodji

Date: Fri Nov 16 15:20:03 2012

New Revision: 193562



URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=193562

Log:

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.



Added:

    trunk/gcc/testsuite/g++.dg/cpp0x/alias-decl-27.C

Modified:

    trunk/gcc/cp/ChangeLog

    trunk/gcc/cp/pt.c

    trunk/gcc/testsuite/ChangeLog

Reply via email to