cplusplus / CWG

Core Working Group
23 stars 7 forks source link

[temp.deduct.decl] Clarify if friend declaration referring to a specialization of a function template when there is no such function template is ill-formed #465

Open ranaanoop opened 10 months ago

ranaanoop commented 10 months ago

Full name of submitter: Anoop Rana Reference (section label): [temp.deduct.decl]

Link to reflector thread (if any):

Issue description:

It should be clarified if the following program containing a friend declaration referring to a specialization of a function template is ill-formed or not. We observe implementation divergence here.

template <class T> 
struct Ext {

   struct Inner
   { 
       int m{};
   };

   friend void fun2<T>(typename Ext<T>::Inner&); //C++20: works in gcc and msvc but rejected by clang   
};

template <class T>
void fun2(typename Ext<T>::Inner &p) 
{ 
     p.m = 10; 
}
int main()
{
    Ext<int>::Inner x; 
    fun2<int>(x); 
}

It seems(afaik) temp.deduct.decl#2 currently makes the program ill-formed as there is no match. But IMO it can be made more clear by adding the phrase "or if the set is empty" as indicated below.

Suggested resolution:

Add a bullet point above temp.deduct.decl#2 as indicated :

If, the set of function templates so considered is empty, the program is ill-formed, or

frederick-vs-ja commented 10 months ago

There doesn't seem an issue for this. How about (editorially) adding a note?

ranaanoop commented 10 months ago

@frederick-vs-ja Notes are mostly informational rather than normative so I think a separate bullet point would be better suited. In other words, since notes are not allowed to include requirements, it would be best to not use note here.

jensmaurer commented 10 months ago

If you omit everything below the definition of "struct Ext", clang still says this is an error. So, clang believes the template declaration of "struct Ext" is ill-formed, regardless of any instantiations.

And that seems plausible, given that the friend refers to a function template specialization, but the function template doesn't exist (at this point), i.e. lookup for the name of the function template fails.

Can you walk us through the "friend" rules what should happen in this case?

ranaanoop commented 10 months ago

Can you walk us through the "friend" rules what should happen in this case?

@jensmaurer temp.friend#1 seems to be applicable. Then temp.deduct.decl.

jensmaurer commented 10 months ago

Not so fast. p1 is just introductory text and doesn't answer the question why name lookup should find anything at all for the example.

temp.friend p2 seems very interesting:

When a template is instantiated, its friend declarations are found by name lookup as if the specialization had been explicitly declared at its point of instantiation.

So, the standard specifies that we delay name lookup for friend declarations to the point of instantiation.

It seems clang doesn't do that. Please post a bug report to clang. Oh, and I'm not seeing anywhere that we'd need deduction for this case; we just perform substitution.

ranaanoop commented 10 months ago

It seems clang doesn't do that. Please post a bug report to clang.

@jensmaurer If you're suggesting that the program is well-formed according to the current wording in the standard and that clang has a bug for the above shown program then I think that this is a defect in the standard. I mean you cannot/shouldnot(in any way) be able to provide(refer to) a specialization without having anything to specialize!. That is, without a primary template declaration, it doesn't make sense to have a declaration of a specialization(be it a friend declaration or any other declaration).

jensmaurer commented 10 months ago

If you're suggesting that the program is well-formed according to the current wording in the standard and that clang has a bug for the above shown program

Well, fun2 is that primary template declaration, right? And temp.friend p2 clearly says we delay the lookup until instantiation time for all friend declarations, in my view.

Do we agree about the status quo of the wording insofar?

ranaanoop commented 10 months ago

@jensmaurer While reading more about this in the standard and searching on web, I came across this thread which currently has two answers both of which seem to say that the program is ill-formed.

frederick-vs-ja commented 10 months ago

@frederick-vs-ja Notes are mostly informational rather than normative so I think a separate bullet point would be better suited. In other words, since notes are not allowed to include requirements, it would be best to not use note here.

I think we can add a note which just clarifies the requirements in normative texts. Did you think that they can't be clarified non-normatively?

jensmaurer commented 8 months ago

So, we seem to agree the example is ill-formed. Maybe we could just add the (simpler) example from the stackoverflow thread to the standard somewhere? Suggestions welcome.