From 70d577644b8d80f4643b113ea596f313e73ac8af Mon Sep 17 00:00:00 2001 From: John McCall Date: Wed, 9 Sep 2015 23:04:17 +0000 Subject: [PATCH] Fix access control for lookups using the Microsoft __super extension. rdar://22464808 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@247207 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Sema/SemaLookup.cpp | 17 +++++++++-- test/SemaCXX/microsoft-super.cpp | 49 ++++++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 test/SemaCXX/microsoft-super.cpp diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp index dc23c13fbb..923da4e06b 100644 --- a/lib/Sema/SemaLookup.cpp +++ b/lib/Sema/SemaLookup.cpp @@ -2098,17 +2098,30 @@ bool Sema::LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, /// /// @returns True if any decls were found (but possibly ambiguous) bool Sema::LookupInSuper(LookupResult &R, CXXRecordDecl *Class) { + // The access-control rules we use here are essentially the rules for + // doing a lookup in Class that just magically skipped the direct + // members of Class itself. That is, the naming class is Class, and the + // access includes the access of the base. for (const auto &BaseSpec : Class->bases()) { CXXRecordDecl *RD = cast( BaseSpec.getType()->castAs()->getDecl()); LookupResult Result(*this, R.getLookupNameInfo(), R.getLookupKind()); Result.setBaseObjectType(Context.getRecordType(Class)); LookupQualifiedName(Result, RD); - for (auto *Decl : Result) - R.addDecl(Decl); + + // Copy the lookup results into the target, merging the base's access into + // the path access. + for (auto I = Result.begin(), E = Result.end(); I != E; ++I) { + R.addDecl(I.getDecl(), + CXXRecordDecl::MergeAccess(BaseSpec.getAccessSpecifier(), + I.getAccess())); + } + + Result.suppressDiagnostics(); } R.resolveKind(); + R.setNamingClass(Class); return !R.empty(); } diff --git a/test/SemaCXX/microsoft-super.cpp b/test/SemaCXX/microsoft-super.cpp new file mode 100644 index 0000000000..bfa9d17dbc --- /dev/null +++ b/test/SemaCXX/microsoft-super.cpp @@ -0,0 +1,49 @@ +// RUN: %clang_cc1 -fms-extensions -verify %s + +// rdar://22464808 + +namespace test0 { + class A { + private: + void foo(int*); + public: + void foo(long*); + }; + class B : public A { + void test() { + __super::foo((long*) 0); + } + }; +} + +namespace test1 { + struct A { + static void foo(); // expected-note {{member is declared here}} + }; + struct B : private A { // expected-note {{constrained by private inheritance here}} + void test() { + __super::foo(); + } + }; + struct C : public B { + void test() { + __super::foo(); // expected-error {{'foo' is a private member of 'test1::A'}} + } + }; +} + +namespace test2 { + struct A { + static void foo(); + }; + struct B : public A { + void test() { + __super::foo(); + } + }; + struct C : private B { + void test() { + __super::foo(); + } + }; +} -- 2.40.0