[PATCH] PR17337 - Retain previous linkage of friend function declarations

Alp Toker alp at nuanti.com
Tue Sep 24 23:23:46 PDT 2013


On 24/09/2013 20:19, Richard Smith wrote:
> On Tue, Sep 24, 2013 at 9:14 AM, Alp Toker <alp at nuanti.com
> <mailto:alp at nuanti.com>> wrote:
>
>     gcc and MSVC both intentionally* retain the language linkage, and
>     they accept both test cases in the PR.
>
>     I already explained in PR17337 why this special handling is
>     important, and it becomes more so in the face of nested language
>     linkage specifications:
>
>       http://llvm.org/bugs/show_bug.cgi?id=17337
>
>     The previous release of clang correctly accepted the code, just
>     like every other C++ compiler, up until checking was added in
>     r171139 / r181163 so this is a recent rejects-valid regression.
>
>
> If you can explain, with references to the standard, why you think we
> should inherit the language linkage, then I'll agree.

Here's your explanation:

[dcl.link] applies only to introduced names and friend functions don't
introduce names. Here's the relevant part of the language reference from
which you can derive your own judgement:

[basic.scope.pdecl]p6:
  friend declarations refer to functions or classes that are members of
  the nearest enclosing namespace, but they **do not introduce** new
  names into that namespace (_namespace.memdef_).

[dcl.link]p4:
  In a linkage-specification,
  the specified language linkage applies to the function  types  of  all
  function declarators, function names, and variable names **introduced** by
  the declaration(s).


I'll also explain the reasoning behind our implementation, which is
borne of practical needs as much as correctness:

Language linkage specifications can only appear at namespace scope
([dcl.link]p4).

So this is invalid:
class ... {
  friend extern "C" int bar(Foo *y);
};

Therefore pre-declaring the desired language linkage and retaining it in
the friend declaration is the _only_ way to implement a friend function
with different language linkage to its declaration context.

Rejecting such code wouldn't appear to benefit the developer, and it
makes impossible something that's within reason and in the spirit of the
language reference.

You mentioned core issue 564 in another thread and I can't see what that
has to do with PR17337.

The C++ specification supports non-core languages as vendor extensions
([dcl.link]p2) and friend functions of varied language would effectively
be unusable in that scenario without retained linkage. GCJ is a good
example of code that relies heavily on retained language linkage to good
effect.

Consider also trivial use cases like debugging and serialization
functions that need access to private class members but would benefit
from C linkage for ABI compatibility or breakpointing.

Keep in mind there's precedent for ignoring language linkage
([dcl.link]p4) for class members, and friend functions are lexically
similar to class members in that they appear in the same written context
-- neither can have an inline language linkage spec. Add it all up and
the semantic that makes sense it to retain.
> As far as I can see, other compilers are getting this wrong. EDG
> rejects the code, just like we do. g++ and MSVC are known to have weak
> implementations of the language linkage rules.
There's every indication that the handling in g++ and MSVC is
intentional, and it's even regression tested in the GNU suite as I cited
earlier. Both compilers have had basic diagnosis of language linkage
since back when clang was still a plain C compiler so it's a bit
disingenuous to put it down to weak implementation on their part.

As for EDG, being a disembodied frontend it has the luxury of taking the
high ground whereas linkage in GNU, MSVC and clang actually goes
somewhere. clang has come a long way and I don't believe EDG is
necessarily the frontend to aspire to in a practical C++ implementation :-)

-- 
http://www.nuanti.com
the browser experts




More information about the cfe-commits mailing list