Skip to content

Commit

Permalink
[Clang][Sema] Fix access of friend class in local class
Browse files Browse the repository at this point in the history
Clang currently emits an error when a friend of a local class
tries to access it's private data members. This patch fixes the bug.

Differential Revision: https://reviews.llvm.org/D152195
  • Loading branch information
elizabethandrews committed Jun 6, 2023
1 parent a279a09 commit c1401e9
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 1 deletion.
3 changes: 3 additions & 0 deletions clang/docs/ReleaseNotes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -539,6 +539,9 @@ Bug Fixes to C++ Support
- Allow omitting ``typename`` in the parameter declaration of a friend
constructor declaration.
(`#63119 <https://github.com/llvm/llvm-project/issues/63119>`_)
- Fix access of a friend class declared in a local class. Clang previously
emitted an error when a friend of a local class tried to access it's
private data members.

Bug Fixes to AST Handling
^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down
5 changes: 4 additions & 1 deletion clang/lib/Sema/SemaDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17066,11 +17066,14 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
S = getTagInjectionScope(S, getLangOpts());
} else {
assert(TUK == TUK_Friend);
CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(SearchDC);

// C++ [namespace.memdef]p3:
// If a friend declaration in a non-local class first declares a
// class or function, the friend class or function is a member of
// the innermost enclosing namespace.
SearchDC = SearchDC->getEnclosingNamespaceContext();
SearchDC = RD->isLocalClass() ? RD->isLocalClass()
: SearchDC->getEnclosingNamespaceContext();
}

// In C++, we need to do a redeclaration lookup to properly
Expand Down
17 changes: 17 additions & 0 deletions clang/test/Sema/local-class-friend.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// RUN: %clang_cc1 -verify -fsyntax-only %s
// expected-no-diagnostics

void foo()
{ class c1 {
private:
int testVar;
public:
friend class c2;
};

class c2 {
void f(c1 obj) {
int a = obj.testVar; // Ok
}
};
}

0 comments on commit c1401e9

Please sign in to comment.