We were missing a way the function being called can be dependent.
Tested x86_64-pc-linux-gnu, applying to 4.8, 4.9, trunk.
commit 687aa57720473c7962c9eb9cf79c67cf068ba005 Author: Jason Merrill <ja...@redhat.com> Date: Mon Jun 30 13:50:38 2014 -0400 PR c++/61647 * pt.c (type_dependent_expression_p): Check BASELINK_OPTYPE. diff --git a/gcc/cp/pt.c b/gcc/cp/pt.c index 3ddd4b8..a188892 100644 --- a/gcc/cp/pt.c +++ b/gcc/cp/pt.c @@ -20011,7 +20011,12 @@ type_dependent_expression_p (tree expression) return true; if (BASELINK_P (expression)) - expression = BASELINK_FUNCTIONS (expression); + { + if (BASELINK_OPTYPE (expression) + && dependent_type_p (BASELINK_OPTYPE (expression))) + return true; + expression = BASELINK_FUNCTIONS (expression); + } if (TREE_CODE (expression) == TEMPLATE_ID_EXPR) { diff --git a/gcc/testsuite/g++.dg/template/conv14.C b/gcc/testsuite/g++.dg/template/conv14.C new file mode 100644 index 0000000..509ae6a --- /dev/null +++ b/gcc/testsuite/g++.dg/template/conv14.C @@ -0,0 +1,30 @@ +// PR c++/61647 + +class XX; + +template<typename Container, typename Key> +struct Accessor; + +template<typename Container, typename Key, typename KeyStore = Key> +class Variant { +protected: + KeyStore index; + Container state; +public: + Variant(Container st, const Key& i) : index(i), state(st) {} + + template<typename T> + operator T() const { + return Accessor<Container, KeyStore>::template get<T>(state, index); + } +}; + +class AutoCleanVariant : public Variant<XX*, int> { +public: + AutoCleanVariant(XX* st, int i) : Variant<XX*,int>(st,i) {} + + template<typename T> + operator T() const { + return Variant<XX*, int>::operator T(); + } +};