[cfe-dev] Clang Sources, friend classes can't access private members?

David Blaikie via cfe-dev cfe-dev at lists.llvm.org
Tue May 7 08:03:00 PDT 2019


On Tue, May 7, 2019 at 7:27 AM via cfe-dev <cfe-dev at lists.llvm.org> wrote:
>
> Hi all!
> I found that in clang sources, in Sema.h in particular,
> it is required to add class predeclaration before friending it, like this:
>
>   class DelayedDiagnostics; // predeclaration is required here, otherwise
it won't compiled
>
>   class DelayedDiagnosticsState {
>     sema::DelayedDiagnosticPool *SavedPool;
>     friend class Sema::DelayedDiagnostics;
>   };
>   // ...
>   class DelayedDiagnostics {
>   // ...
>     DelayedDiagnosticsState push(sema::DelayedDiagnosticPool &pool) {
>       DelayedDiagnosticsState state;
>       state.SavedPool = CurPool; // Private access.
>       // ...
>     }
>   };
>
> And yet it contradicts standard, which states that the name of the class
that is used in this friend declaration does not need to be previously
declared.
>
> Honestly I didn't try to debug it. I tried to reproduce it though, but
failed. The example below compiled with no errors:
>
> namespace clang {
> class Sema {
>   public:
>   class A {
>     int x;
>     friend class B;
>   };
>
>   class B {
>     A a;
>     void f() {
>       a.x = 1; // access private member of A, no error!
>     }
>   };
> };
> } // namespace clang
>
> It looks like I'm missing something... Anybody knows why we should
predeclare friend classes in clang::Sema?

I can't reproduce your minimized test case - when I try to compile the
example you gave, I get an error:

delay.cpp:12:9: error: 'x' is a private member of 'clang::Sema::A'
      a.x = 1;  // access private member of A, no error!
        ^
delay.cpp:5:9: note: implicitly declared private here
    int x;
        ^
1 error generated.

But if you make 'B' not a member of 'Sema', but instead just a member of
the 'clang' namespace, then it compiles - which shows the difference
between your example and the original. In the original code, it says
"friend class Sema::B", whereas your example is "friend class B" - in the
latter case, that unqualified 'class B' (in the absence of a prior
declaration of 'class B' inside class Sema) refers to/injects a declaration
of 'B' into the clang namespace, not into the Sema class.

>
> Thanks!
> Stepan Dyatkovskiy
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20190507/9a1a8ef2/attachment.html>


More information about the cfe-dev mailing list