When filtering out previous declarations of friend functions, consider the
lookup context, not the direct semantic context. Fixes PR7230. llvm-svn: 104917
This commit is contained in:
parent
3743b8cf49
commit
4583186b8b
|
@ -5762,13 +5762,18 @@ Sema::ActOnFriendFunctionDecl(Scope *S,
|
|||
|
||||
LookupQualifiedName(Previous, DC);
|
||||
|
||||
// If searching in that context implicitly found a declaration in
|
||||
// a different context, treat it like it wasn't found at all.
|
||||
// Ignore things found implicitly in the wrong scope.
|
||||
// TODO: better diagnostics for this case. Suggesting the right
|
||||
// qualified scope would be nice...
|
||||
// FIXME: getRepresentativeDecl() is not right here at all
|
||||
if (Previous.empty() ||
|
||||
!Previous.getRepresentativeDecl()->getDeclContext()->Equals(DC)) {
|
||||
LookupResult::Filter F = Previous.makeFilter();
|
||||
while (F.hasNext()) {
|
||||
NamedDecl *D = F.next();
|
||||
if (!D->getDeclContext()->getLookupContext()->Equals(DC))
|
||||
F.erase();
|
||||
}
|
||||
F.done();
|
||||
|
||||
if (Previous.empty()) {
|
||||
D.setInvalidType();
|
||||
Diag(Loc, diag::err_qualified_friend_not_found) << Name << T;
|
||||
return DeclPtrTy();
|
||||
|
|
|
@ -6,9 +6,6 @@
|
|||
// its friends, if any, by way of friend declarations. Such declarations give
|
||||
// special access rights to the friends, but they do not make the nominated
|
||||
// friends members of the befriending class.
|
||||
//
|
||||
// FIXME: Add tests for access control when implemented. Currently we only test
|
||||
// for parsing.
|
||||
|
||||
struct S { static void f(); };
|
||||
S* g() { return 0; }
|
||||
|
@ -287,3 +284,25 @@ namespace test9 {
|
|||
friend class test9;
|
||||
};
|
||||
}
|
||||
|
||||
// PR7230
|
||||
namespace test10 {
|
||||
extern "C" void f(void);
|
||||
extern "C" void g(void);
|
||||
|
||||
namespace NS {
|
||||
class C {
|
||||
void foo(void); // expected-note {{declared private here}}
|
||||
friend void test10::f(void);
|
||||
};
|
||||
static C* bar;
|
||||
}
|
||||
|
||||
void f(void) {
|
||||
NS::bar->foo();
|
||||
}
|
||||
|
||||
void g(void) {
|
||||
NS::bar->foo(); // expected-error {{private member}}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue