[PATCH] D19336: Repair redeclaration chain of friend template functions.

Serge Pavlov via cfe-commits cfe-commits at lists.llvm.org
Mon Apr 25 10:39:57 PDT 2016


2016-04-21 2:57 GMT+06:00 Richard Smith <richard at metafoo.co.uk>:

> rsmith added a comment.
>
> Sorry, I don't think this approach can work. Consider:
>
>   template<typename T> struct X {
>     template<typename U> friend void f(T);
>     template<typename U> friend void f(U);
>   };
>
> These two friend declarations declare different friend function templates,
> but this transformation would incorrectly make them have the same type and
> be redeclarations of each other.
>
>  Yes, it's true, thank you for the example. I think dependent friend
template functions should not be added into redeclaration chains.

I think the right thing here is to just accept that a friend function
> template declared within a class template will not be part of the
> corresponding redeclaration chain. But that's fine, so long as we don't try
> to inject the function template into the surrounding scope -- when we come
> to instantiate the class template, the instantiated friend function
> template will have the right type and will be part of the relevant
> redeclaration chain.
>
> Redeclaration chain of templates are useful for checking semantics of
templates, not instantiated entities, which have own redeclaration chains.
Particular task for which this fix should be useful is implementation of
default template arguments of friend functions. Now clang do not allow to
specify them, but the standard allow [temp.parap]p9 : "... If a friend
function template declaration specifies a default template-argument, that
declaration shall be a definition and shall be the only declaration of the
function template in the translation unit". The mentioned condition could
be checked using redeclaration chain of templates, if the chain was built
correctly.

The main problem related to the redeclaration chains is similar to that
solved by http://reviews.llvm.org/D16989. Clang and GCC now treat friend
function definitions differently. The following code:

template<typename T1> void func();

template<typename T>
struct C1 {
  template<typename T1> friend void func() {}
};

int main(int argc, char *argv[]) {
  func<int>();
}


produces error at link stage if GCC is used, due to unresolved reference to
func<int>().  Clang compiles this code successfully, it sees the definition
of func inside struct C1. GCC sees it only if host template is instantiated.

It makes sense to finish http://reviews.llvm.org/D16989 first. Many of
problems related to not-template friend functions seem to be applicable to
templates as well.

Thanks,
--Serge


<https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail>
Без
вирусов. www.avast.com
<https://www.avast.com/sig-email?utm_medium=email&utm_source=link&utm_campaign=sig-email&utm_content=webmail>
<#DDB4FAA8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160425/c534f2f8/attachment-0001.html>


More information about the cfe-commits mailing list