diff options
-rw-r--r-- | include/clang/AST/UnresolvedSet.h | 4 | ||||
-rw-r--r-- | lib/Sema/SemaDeclCXX.cpp | 5 | ||||
-rw-r--r-- | lib/Sema/SemaOverload.cpp | 6 | ||||
-rw-r--r-- | test/CXX/class.access/p4.cpp | 10 |
4 files changed, 22 insertions, 3 deletions
diff --git a/include/clang/AST/UnresolvedSet.h b/include/clang/AST/UnresolvedSet.h index d2e33edf08..8bf7c11e6f 100644 --- a/include/clang/AST/UnresolvedSet.h +++ b/include/clang/AST/UnresolvedSet.h @@ -147,6 +147,10 @@ public: decls().pop_back(); } + void setAccess(iterator I, AccessSpecifier AS) { + I.ir->setInt(AS); + } + void clear() { decls().clear(); } void set_size(unsigned N) { decls().set_size(N); } diff --git a/lib/Sema/SemaDeclCXX.cpp b/lib/Sema/SemaDeclCXX.cpp index f65dc4bd66..566e915bc0 100644 --- a/lib/Sema/SemaDeclCXX.cpp +++ b/lib/Sema/SemaDeclCXX.cpp @@ -2086,6 +2086,11 @@ void Sema::CheckCompletedCXXClass(CXXRecordDecl *Record) { if (Record->isInvalidDecl()) return; + // Set access bits correctly on the directly-declared conversions. + UnresolvedSetImpl *Convs = Record->getConversionFunctions(); + for (UnresolvedSetIterator I = Convs->begin(), E = Convs->end(); I != E; ++I) + Convs->setAccess(I, (*I)->getAccess()); + if (!Record->isAbstract()) { // Collect all the pure virtual methods and see if this is an abstract // class after all. diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp index 55259fca4f..86b1e37f10 100644 --- a/lib/Sema/SemaOverload.cpp +++ b/lib/Sema/SemaOverload.cpp @@ -6231,7 +6231,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, = cast<CXXConversionDecl>( Best->Conversions[0].UserDefined.ConversionFunction); - // FIXME: access control + CheckMemberOperatorAccess(LParenLoc, Object, Conv, Best->getAccess()); // We selected one of the surrogate functions that converts the // object parameter to a function pointer. Perform the conversion @@ -6246,8 +6246,8 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Object, CommaLocs, RParenLoc).release(); } - if (getLangOptions().AccessControl) - CheckAccess(R, Best->Function, Best->getAccess()); + CheckMemberOperatorAccess(LParenLoc, Object, + Best->Function, Best->getAccess()); // We found an overloaded operator(). Build a CXXOperatorCallExpr // that calls this method, using Object for the implicit object diff --git a/test/CXX/class.access/p4.cpp b/test/CXX/class.access/p4.cpp index 0df17919a3..97c632a072 100644 --- a/test/CXX/class.access/p4.cpp +++ b/test/CXX/class.access/p4.cpp @@ -39,15 +39,21 @@ namespace test1 { void operator+(Public&); void operator[](Public&); void operator()(Public&); + typedef void (*PublicSurrogate)(Public&); + operator PublicSurrogate() const; protected: void operator+(Protected&); // expected-note {{declared protected here}} void operator[](Protected&); // expected-note {{declared protected here}} void operator()(Protected&); // expected-note {{declared protected here}} + typedef void (*ProtectedSurrogate)(Protected&); + operator ProtectedSurrogate() const; // expected-note {{declared protected here}} private: void operator+(Private&); // expected-note {{declared private here}} void operator[](Private&); // expected-note {{declared private here}} void operator()(Private&); // expected-note {{declared private here}} void operator-(); // expected-note {{declared private here}} + typedef void (*PrivateSurrogate)(Private&); + operator PrivateSurrogate() const; // expected-note {{declared private here}} }; void operator+(const A &, Public&); void operator+(const A &, Protected&); @@ -71,5 +77,9 @@ namespace test1 { ca + prot; ca + priv; -ca; + // These are all surrogate calls + ca(pub); + ca(prot); // expected-error {{access to protected member}} + ca(priv); // expected-error {{access to private member}} } } |