gcc 4.2 accepts the following program: class B { public: void b(int a); void c(int a); }; class A { private: static int a(); friend void B::c(int); }; //void B::b(int a = A::a()) {} // Should error void B::c(int a = A::a()) {} clang rejects it with test.cc:14:22: error: 'a' is a private member of 'A' void B::c(int a = A::a()) {} ^ test.cc:9:14: note: declared private here static int a(); ^ 1 error generated. (Reverting r120299 does not make this go away.)
Here is another example: class A { void a(int); }; class B { static int x; friend void A::a(int); friend void f(int); }; void A::a(int foo = B::x) {} // This does not compile. void f(int foo = B::x) {} // This compiles. The reason the first function doesn't compile is that the access control check for the name in the default argument expression is performed before the declarator has been fully parsed. This means that the EffectiveContext used by CheckAccess doesn't contain any functions. Since there are no functions, nothing is matched by the friend declaration. For the non-member function f, it works because access control check gets delayed. There's a comment about this (SemaAccess.cpp:1263) that says "If we're currently parsing a top-level declaration, delay diagnostics." I'm not really sure why. Is there a way to delay diagnostics for the member function declaration in this case? Or to get the DeclContext set sooner? I'd be happy to try to come up with a patch if someone could point me in the right direction.
Fixed in r125485.