Bug 182081

Summary: [Win] MSVC doesn't seem to like "friend class NeverDestroyed<Foo>"
Product: WebKit Reporter: Fujii Hironori <Hironori.Fujii>
Component: WebKit Misc.Assignee: Fujii Hironori <Hironori.Fujii>
Status: RESOLVED FIXED    
Severity: Normal CC: achristensen, Basuke.Suzuki, bfulgham, commit-queue, jiewen_tan, pvollan, webkit-bug-importer, Yousuke.Kimoto, ysuzuki
Priority: P2 Keywords: InRadar
Version: WebKit Nightly Build   
Hardware: Unspecified   
OS: Unspecified   
Bug Depends on:    
Bug Blocks: 177202    
Attachments:
Description Flags
Patch none

Description Fujii Hironori 2018-01-24 18:27:44 PST
[Win] MSVC doesn't seem to like "friend class NeverDestroyed<Foo>"

While trying to build WebKit2 for Windows (Bug 181885), I see a lot of compilation errors that NeverDestroyed is not a friend like following:

> 1>------ Build started: Project: WebKit (WebKit\WebKit), Configuration: Debug x64 ------
> 1>NetworkProcess.cpp
> 1>C:\webkit\gb\WebKitBuild\Debug\DerivedSources\ForwardingHeaders\wtf/NeverDestroyed.h(50): error C2248: 'WebKit::NetworkProcess::NetworkProcess': cannot access private member declared in class 'WebKit::NetworkProcess'
> 1>C:\webkit\gb\Source\WebKit\NetworkProcess\NetworkProcess.cpp(104): note: see declaration of 'WebKit::NetworkProcess::NetworkProcess'
> 1>c:\webkit\gb\source\webkit\networkprocess\NetworkProcess.h(79): note: see declaration of 'WebKit::NetworkProcess'
> 1>C:\webkit\gb\Source\WebKit\NetworkProcess\NetworkProcess.cpp(100): note: see reference to function template instantiation 'WTF::NeverDestroyed<WebKit::NetworkProcess>::NeverDestroyed<>(void)' being compiled
> 1>C:\webkit\gb\Source\WebKit\NetworkProcess\NetworkProcess.cpp(100): note: see reference to function template instantiation 'WTF::NeverDestroyed<WebKit::NetworkProcess>::NeverDestroyed<>(void)' being compiled
> 1>Done building project "WebKit.vcxproj" -- FAILED.
> ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

If I apply a following patch, it can build:

> diff --git a/Source/WebKit/NetworkProcess/NetworkProcess.h b/Source/WebKit/NetworkProcess/NetworkProcess.h
> index a9c9818dd03..15a7469cb23 100644
> --- a/Source/WebKit/NetworkProcess/NetworkProcess.h
> +++ b/Source/WebKit/NetworkProcess/NetworkProcess.h
> @@ -78,8 +78,8 @@ class Cache;
>  
>  class NetworkProcess : public ChildProcess, private DownloadManager::Client {
>      WTF_MAKE_NONCOPYABLE(NetworkProcess);
> -    friend class NeverDestroyed<NetworkProcess>;
> -    friend class NeverDestroyed<DownloadManager>;
> +    friend NeverDestroyed<NetworkProcess>;
> +    friend NeverDestroyed<DownloadManager>;
>  public:
>      static NetworkProcess& singleton();
>
Comment 1 Fujii Hironori 2018-01-24 18:29:33 PST
(In reply to Fujii Hironori from comment #0)
> [Win] MSVC doesn't seem to like "friend class NeverDestroyed<Foo>"
> 
> While trying to build WebKit2 for Windows (Bug 181885), 

Incorrect bug id. it's Bug 177202.
Comment 2 Fujii Hironori 2018-01-24 18:52:06 PST
I can't find an answer in this page.

friend declaration - cppreference.com
http://en.cppreference.com/w/cpp/language/friend
Comment 3 Fujii Hironori 2018-01-24 19:22:13 PST
https://timsong-cpp.github.io/cppwp/n4140/temp.friend

> template<class T> class task;
> template<class T> task<T>* preempt(task<T>*);
> 
> template<class T> class task {
>   friend void next_time();
>   friend void process(task<T>*);
>   friend task<T>* preempt<T>(task<T>*);
>   template<class C> friend int func(C);
> 
>   friend class task<int>;
>   template<class P> friend class frd;
> };
[...]
> [...] Similarly, each specialization of the task class template has the class template specialization task<int> as a friend, [...]

If I understand correctly, "friend class NeverDestroyed<Foo>" is a valid style.
Comment 4 Fujii Hironori 2018-01-24 19:26:58 PST
Specifying command line switch /std:c++14, /std:c++17 or /std:c++latest doesn't help at all. (I'm using VS 2017 version 15.5.2)
Comment 5 Fujii Hironori 2018-01-24 21:09:31 PST
Repro: <https://gist.github.com/fujii/fea40827887237053b537f48807a8963>
The template friend class, which belongs to a different namespace, can't access private member if its friend declaration is specified without the namespace and with class keyword.
I sent a bug report to MS compiler team.
Comment 6 Fujii Hironori 2018-01-25 18:53:37 PST
I got their reply:

> Looks like this is already fixed with VS2017 15.6 preview 3.

I also confirmed this problem was fixed by it.
Comment 7 Fujii Hironori 2018-02-01 17:26:57 PST
can't wait VS2017 15.6 release. reopen.
Comment 8 Fujii Hironori 2018-02-01 17:43:26 PST
Created attachment 332926 [details]
Patch
Comment 9 Yusuke Suzuki 2018-02-02 09:13:40 PST
Comment on attachment 332926 [details]
Patch

r=me
Comment 10 WebKit Commit Bot 2018-02-02 11:38:11 PST
Comment on attachment 332926 [details]
Patch

Clearing flags on attachment: 332926

Committed r228021: <https://trac.webkit.org/changeset/228021>
Comment 11 WebKit Commit Bot 2018-02-02 11:38:14 PST
All reviewed patches have been landed.  Closing bug.
Comment 12 Radar WebKit Bug Importer 2018-02-02 11:40:18 PST
<rdar://problem/37164230>