This backport contains 1 patch from gcc main stream tree. The commit id of these patchs list as following in the order of time. 0001-Fix-interaction-between-aka-changes-and-DR1558.patch ae83b9deb87787371cd94b4417e160d41dd0322c diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index adc021b2a5c..42afe1bd5cb 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -5759,8 +5759,13 @@ enum auto_deduction_context STF_USER_VISIBLE: use heuristics to try to avoid stripping user-facing aliases of internal details. This is intended for diagnostics, - where it should (for example) give more useful "aka" types. */ + where it should (for example) give more useful "aka" types. + + STF_STRIP_DEPENDENT: allow the stripping of aliases with dependent + template parameters, relying on code elsewhere to report any + appropriate diagnostics. */ const unsigned int STF_USER_VISIBLE = 1U; +const unsigned int STF_STRIP_DEPENDENT = 1U << 1; /* Returns the TEMPLATE_DECL associated to a TEMPLATE_TEMPLATE_PARM node. */ diff --git a/gcc/cp/tree.c b/gcc/cp/tree.c index ba635d4ddbd..6c39c004b01 100644 --- a/gcc/cp/tree.c +++ b/gcc/cp/tree.c @@ -1488,7 +1488,8 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags) if (t == TYPE_CANONICAL (t)) return t; - if (dependent_alias_template_spec_p (t)) + if (!(flags & STF_STRIP_DEPENDENT) + && dependent_alias_template_spec_p (t)) /* DR 1558: However, if the template-id is dependent, subsequent template argument substitution still applies to the template-id. */ return t; @@ -1673,7 +1674,8 @@ strip_typedefs (tree t, bool *remove_attributes, unsigned int flags) && !user_facing_original_type_p (t)) return t; result = strip_typedefs (DECL_ORIGINAL_TYPE (TYPE_NAME (t)), - remove_attributes, flags); + remove_attributes, + flags | STF_STRIP_DEPENDENT); } else result = TYPE_MAIN_VARIANT (t); diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-1.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-1.C new file mode 100644 index 00000000000..c3f7b1977db --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-1.C @@ -0,0 +1,9 @@ +// { dg-require-effective-target c++11 } + +template struct A {}; +template using alias1 = A; +template class B { + using alias2 = alias1>; // { dg-error {no type named 'value'} } + A a; // { dg-bogus {no type named 'value'} } +}; +B b; diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-2.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-2.C new file mode 100644 index 00000000000..31d73d6bad3 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-2.C @@ -0,0 +1,14 @@ +// { dg-require-effective-target c++11 } + +template struct A; +class Vector { + template struct TypeIsGCThing { + template ::Type> using Vector = Vector; + struct B; + template class ContainerIter { + using Action = B; + using ActionVector = Vector; + ContainerIter a; + }; + }; +}; diff --git a/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-3.C b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-3.C new file mode 100644 index 00000000000..6698a366411 --- /dev/null +++ b/gcc/testsuite/g++.dg/cpp0x/alias-decl-pr92206-3.C @@ -0,0 +1,8 @@ +// { dg-require-effective-target c++11 } + +template void a(); +template struct b; +template using c = int; +template )> using f = e; +template using g = f; +template c>::i> j;