The previous language linkage needs to be retained as described in [class.friend]p3 otherwise valid friend redeclarations differing only in lexical linkage are rejected.
Fixes PR17337. -- http://www.nuanti.com the browser experts
commit f694eb6a21cfbefe68ae45123f897c1de40a0ff5 Author: Alp Toker <[email protected]> Date: Tue Sep 24 10:28:40 2013 +0100 Retain previous linkage of friend function declarations The previous language linkage needs to be retained as described in [class.friend]p3 otherwise valid friend redeclarations differing only in lexical linkage are rejected. Fixes PR17337. diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 92400df..1b0a89f 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -2217,6 +2217,13 @@ static bool haveIncompatibleLanguageLinkages(const T *Old, const T *New) { if (DC->isRecord()) return false; + // C++ [class.friend]p3: + // A function first declared in a friend declaration has external linkage. + // Otherwise, the function retains its previous linkage. + // The friend object kind is set later so we check the IDNS directly. + if (New->getIdentifierNamespace() & Decl::IDNS_OrdinaryFriend) + return false; + LanguageLinkage OldLinkage = Old->getLanguageLinkage(); if (OldLinkage == CXXLanguageLinkage && New->isInExternCContext()) return true; diff --git a/test/SemaCXX/linkage2.cpp b/test/SemaCXX/linkage2.cpp index 075f5e7..dde239f 100644 --- a/test/SemaCXX/linkage2.cpp +++ b/test/SemaCXX/linkage2.cpp @@ -213,3 +213,17 @@ namespace PR16247 { void pr16247_bar(int) {} void pr16247_bar(double) {} } + +namespace PR17337 { + extern "C++" { + class Foo; + extern "C" int bar3(Foo *y); + class Foo { + int x; + friend int bar3(Foo *y); + }; + extern "C" int bar3(Foo *y) { + return y->x; + } + } +}
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
