diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-10-09 22:38:36 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-10-09 22:38:36 +0000 |
commit | ac57f0b9097e04f70a631549383a2944f74ad844 (patch) | |
tree | 65de43b5481fcb0b85e0fdcbfb0011835576410c | |
parent | 6c73a2975ba9112787380abd878876336957b3f6 (diff) |
The effective context of a friend function is its lexical
context. Fixes PR9103.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@141520 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/Sema/SemaAccess.cpp | 6 | ||||
-rw-r--r-- | test/CXX/class.access/class.friend/p1.cpp | 13 | ||||
-rw-r--r-- | test/CXX/class.access/class.protected/p1.cpp | 2 |
3 files changed, 19 insertions, 2 deletions
diff --git a/lib/Sema/SemaAccess.cpp b/lib/Sema/SemaAccess.cpp index 14c8ebafe7..d322ebd410 100644 --- a/lib/Sema/SemaAccess.cpp +++ b/lib/Sema/SemaAccess.cpp @@ -103,7 +103,11 @@ struct EffectiveContext { } else if (isa<FunctionDecl>(DC)) { FunctionDecl *Function = cast<FunctionDecl>(DC)->getCanonicalDecl(); Functions.push_back(Function); - DC = Function->getDeclContext(); + + if (Function->getFriendObjectKind()) + DC = Function->getLexicalDeclContext(); + else + DC = Function->getDeclContext(); } else if (DC->isFileContext()) { break; } else { diff --git a/test/CXX/class.access/class.friend/p1.cpp b/test/CXX/class.access/class.friend/p1.cpp index 1668155c18..68ff83fee8 100644 --- a/test/CXX/class.access/class.friend/p1.cpp +++ b/test/CXX/class.access/class.friend/p1.cpp @@ -341,3 +341,16 @@ namespace test12 { void *var = static_cast<B*>(this)->mem; } } + +namespace PR9103 { + struct base { + protected: + static void foo(void) {} + }; + + struct cls: base { + friend void bar(void) { + base::foo(); + } + }; +} diff --git a/test/CXX/class.access/class.protected/p1.cpp b/test/CXX/class.access/class.protected/p1.cpp index 8698fb1da8..79bb6cd67e 100644 --- a/test/CXX/class.access/class.protected/p1.cpp +++ b/test/CXX/class.access/class.protected/p1.cpp @@ -423,7 +423,7 @@ namespace test12 { // This friendship is not considered because a public member of A is // inaccessible in C. namespace test13 { - class A { protected: int foo(); }; // expected-note {{declared protected here}} + class A { protected: int foo(); }; // expected-note {{object type 'test13::D' must derive from context type 'test13::C'}} class B : private virtual A {}; class C : private B { friend void test(); }; class D : public virtual A {}; |