Hi again,
On 08/23/2012 05:53 PM, Paolo Carlini wrote:
On 08/23/2012 05:24 PM, Jason Merrill wrote:
On 08/23/2012 10:04 AM, Paolo Carlini wrote:
+ if (decl
+ && TREE_CODE (decl) == VAR_DECL
+ && ! TYPE_P (CP_DECL_CONTEXT (decl)))
+ {
+ error_at (decl_spec_token_start->location,
+ "%qT is not a template type", TREE_TYPE (decl));
+ decl = error_mark_node;
+ }
Can we just check whether decl has DECL_TEMPLATE_INFO at this point?
I tried, possibly together with a preliminary DECL_LANG_SPECIFIC check
and maybe a check that decl isn't already error_mark_node, but anyway
apparently the idea has issues with friends, testcases like
template/friend17.C (gave me already headaches earlier today, that's
why I'm so quick at replying ;)
template <class T>
struct X {
template <class U> void operator+=(U);
template <class V>
template <class U>
friend void X<V>::operator+=(U);
};
int main() {
X<int>() += 1.0;
}
when we parse the friend declaration, DECL_TEMPLATE_INFO is not set.
I looked somewhat more into this and I haven't been able to find a
simple way to just use DECL_TEMPLATE_INFO. If I arrange to cope with
friend17.C by explicitly excluding TEMPLATE_DECLs like in:
else if (decl != error_mark_node
&& TREE_CODE (decl) != TEMPLATE_DECL
&& (!DECL_LANG_SPECIFIC (decl)
|| !DECL_TEMPLATE_INFO (decl)))
{
error_at (decl_spec_token_start->location,
"%qT is not a template type", TREE_TYPE (decl));
decl = error_mark_node;
}
then we regress eg, g++.dg/cpp0x/temp_default4.C, because in that case,
again involving friends, we have:
lass X {
template<typename T = int> friend void f(X) { }
template<typename T> friend void g(X); // { dg-error "previously
declared here" }
template<typename T = int> friend void h(X); // { dg-error "function
template friend" }
};
template<typename T = int> void g(X) // { dg-error "default template
argument" }
{
}
and the out of class g is a FUNCTION_DECL with again DECL_TEMPLATE_INFO
not set.
Do you have in mind something more specific?
Ah, just in case you wondered (like me ;) we do *not* have an issue with
things like:
template<> int i(int);
which obviously aren't VAR_DECLs, because those are handled already by
check_explicit_specialization.
What about adding a comment about the latter point?
Thanks,
Paolo.