diff --git a/gcc/cp/ChangeLog b/gcc/cp/ChangeLog index 7d4af6d7e49..be248e1f400 100644 --- a/gcc/cp/ChangeLog +++ b/gcc/cp/ChangeLog @@ -1,3 +1,13 @@ +2014-02-21 Jason Merrill + + PR c++/60167 + PR c++/60222 + PR c++/58606 + * parser.c (cp_parser_template_argument): Restore dereference. + * pt.c (template_parm_to_arg): Dereference non-pack expansions too. + (process_partial_specialization): Handle deref. + (unify): Likewise. + 2014-02-21 Adam Butcher PR c++/60052 diff --git a/gcc/cp/parser.c b/gcc/cp/parser.c index 1e4e3df532b..e067a0264ec 100644 --- a/gcc/cp/parser.c +++ b/gcc/cp/parser.c @@ -13937,6 +13937,7 @@ cp_parser_template_argument (cp_parser* parser) if (INDIRECT_REF_P (argument)) { + /* Strip the dereference temporarily. */ gcc_assert (REFERENCE_REF_P (argument)); argument = TREE_OPERAND (argument, 0); } @@ -13975,6 +13976,8 @@ cp_parser_template_argument (cp_parser* parser) if (address_p) argument = build_x_unary_op (loc, ADDR_EXPR, argument, tf_warning_or_error); + else + argument = convert_from_reference (argument); return argument; } } diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 6477fce7aab..4cf387a1d68 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -3861,6 +3861,8 @@ template_parm_to_arg (tree t) SET_ARGUMENT_PACK_ARGS (t, vec); TREE_TYPE (t) = type; } + else + t = convert_from_reference (t); } return t; } @@ -4218,10 +4220,12 @@ process_partial_specialization (tree decl) if (/* These first two lines are the `non-type' bit. */ !TYPE_P (arg) && TREE_CODE (arg) != TEMPLATE_DECL - /* This next line is the `argument expression is not just a + /* This next two lines are the `argument expression is not just a simple identifier' condition and also the `specialized non-type argument' bit. */ - && TREE_CODE (arg) != TEMPLATE_PARM_INDEX) + && TREE_CODE (arg) != TEMPLATE_PARM_INDEX + && !(REFERENCE_REF_P (arg) + && TREE_CODE (TREE_OPERAND (arg, 0)) == TEMPLATE_PARM_INDEX)) { if ((!packed_args && tpd.arg_uses_template_parms[i]) || (packed_args && uses_template_parms (arg))) @@ -17893,6 +17897,12 @@ unify (tree tparms, tree targs, tree parm, tree arg, int strict, /* Unification fails if we hit an error node. */ return unify_invalid (explain_p); + case INDIRECT_REF: + if (REFERENCE_REF_P (parm)) + return unify (tparms, targs, TREE_OPERAND (parm, 0), arg, + strict, explain_p); + /* FALLTHRU */ + default: /* An unresolved overload is a nondeduced context. */ if (is_overloaded_fn (parm) || type_unknown_p (parm)) diff --git a/gcc/testsuite/g++.dg/template/ref7.C b/gcc/testsuite/g++.dg/template/ref7.C new file mode 100644 index 00000000000..f6395e2c35f --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ref7.C @@ -0,0 +1,10 @@ +// PR c++/60167 + +template +struct Foo { + typedef int Bar; + + static Bar cache; +}; + +template typename Foo::Bar Foo::cache; diff --git a/gcc/testsuite/g++.dg/template/ref8.C b/gcc/testsuite/g++.dg/template/ref8.C new file mode 100644 index 00000000000..a2fc8471996 --- /dev/null +++ b/gcc/testsuite/g++.dg/template/ref8.C @@ -0,0 +1,8 @@ +// PR c++/60222 + +template struct A +{ + template struct B; + + template struct B {}; +};