diff options
Diffstat (limited to 'clang/lib')
| -rw-r--r-- | clang/lib/Sema/Sema.h | 2 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaAccess.cpp | 19 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaInit.cpp | 44 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaInit.h | 12 | 
4 files changed, 60 insertions, 17 deletions
diff --git a/clang/lib/Sema/Sema.h b/clang/lib/Sema/Sema.h index 54d36357be2..1595941651f 100644 --- a/clang/lib/Sema/Sema.h +++ b/clang/lib/Sema/Sema.h @@ -2415,6 +2415,8 @@ public:    bool CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,                                     NamedDecl *D,                                     AccessSpecifier Access); +  bool CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, +                              AccessSpecifier Access);    bool CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr,                                   NamedDecl *D, AccessSpecifier Access);    bool CheckAccess(const LookupResult &R, NamedDecl *D, AccessSpecifier Access); diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp index 34c9718014c..ceee61df23a 100644 --- a/clang/lib/Sema/SemaAccess.cpp +++ b/clang/lib/Sema/SemaAccess.cpp @@ -306,7 +306,24 @@ bool Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,    return false;  } -/// Checks access to an overloaded member operator. +/// Checks access to a constructor. +bool Sema::CheckConstructorAccess(SourceLocation UseLoc, +                                  CXXConstructorDecl *Constructor, +                                  AccessSpecifier Access) { +  if (!getLangOptions().AccessControl) +    return false; + +  CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(Constructor->getParent()); + +  LookupResult R(*this, Constructor->getDeclName(), UseLoc, LookupOrdinaryName); +  R.suppressDiagnostics(); + +  R.setNamingClass(NamingClass); +  return CheckAccess(R, Constructor, Access); +} + +/// Checks access to an overloaded member operator, including +/// conversion operators.  bool Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,                                       Expr *ObjectExpr,                                       NamedDecl *MemberOperator, diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index db888a62a4f..4f23751e735 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -1971,7 +1971,8 @@ void InitializationSequence::AddAddressOverloadResolutionStep(    Step S;    S.Kind = SK_ResolveAddressOfOverloadedFunction;    S.Type = Function->getType(); -  S.Function = Function; +  // Access is currently ignored for these. +  S.Function = DeclAccessPair::make(Function, AccessSpecifier(0));    Steps.push_back(S);  } @@ -1992,11 +1993,12 @@ void InitializationSequence::AddReferenceBindingStep(QualType T,  }  void InitializationSequence::AddUserConversionStep(FunctionDecl *Function, +                                                   AccessSpecifier Access,                                                     QualType T) {    Step S;    S.Kind = SK_UserConversion;    S.Type = T; -  S.Function = Function; +  S.Function = DeclAccessPair::make(Function, Access);    Steps.push_back(S);  } @@ -2029,11 +2031,12 @@ void InitializationSequence::AddListInitializationStep(QualType T) {  void   InitializationSequence::AddConstructorInitializationStep(                                                CXXConstructorDecl *Constructor, +                                                       AccessSpecifier Access,                                                           QualType T) {    Step S;    S.Kind = SK_ConstructorInitialization;    S.Type = T; -  S.Function = Constructor; +  S.Function = DeclAccessPair::make(Constructor, Access);    Steps.push_back(S);  } @@ -2246,7 +2249,8 @@ static OverloadingResult TryRefInitWithConversionFunction(Sema &S,      T2 = cv1T1;    // Add the user-defined conversion step. -  Sequence.AddUserConversionStep(Function, T2.getNonReferenceType()); +  Sequence.AddUserConversionStep(Function, Best->getAccess(), +                                 T2.getNonReferenceType());    // Determine whether we need to perform derived-to-base or     // cv-qualification adjustments. @@ -2577,10 +2581,11 @@ static void TryConstructorInitialization(Sema &S,    // Add the constructor initialization step. Any cv-qualification conversion is    // subsumed by the initialization.    if (Kind.getKind() == InitializationKind::IK_Copy) { -    Sequence.AddUserConversionStep(Best->Function, DestType); +    Sequence.AddUserConversionStep(Best->Function, Best->getAccess(), DestType);    } else {      Sequence.AddConstructorInitializationStep(                                        cast<CXXConstructorDecl>(Best->Function),  +                                      Best->getAccess(),                                        DestType);    }  } @@ -2778,13 +2783,13 @@ static void TryUserDefinedConversion(Sema &S,    if (isa<CXXConstructorDecl>(Function)) {      // Add the user-defined conversion step. Any cv-qualification conversion is      // subsumed by the initialization. -    Sequence.AddUserConversionStep(Function, DestType); +    Sequence.AddUserConversionStep(Function, Best->getAccess(), DestType);      return;    }    // Add the user-defined conversion step that calls the conversion function.    QualType ConvType = Function->getResultType().getNonReferenceType(); -  Sequence.AddUserConversionStep(Function, ConvType); +  Sequence.AddUserConversionStep(Function, Best->getAccess(), ConvType);    // If the conversion following the call to the conversion function is     // interesting, add it as a separate step. @@ -3250,7 +3255,9 @@ InitializationSequence::Perform(Sema &S,      case SK_ResolveAddressOfOverloadedFunction:        // Overload resolution determined which function invoke; update the         // initializer to reflect that choice. -      CurInit = S.FixOverloadedFunctionReference(move(CurInit), Step->Function); +      // Access control was done in overload resolution. +      CurInit = S.FixOverloadedFunctionReference(move(CurInit), +                              cast<FunctionDecl>(Step->Function.getDecl()));        break;      case SK_CastDerivedToBaseRValue: @@ -3329,13 +3336,14 @@ InitializationSequence::Perform(Sema &S,        // or a conversion function.        CastExpr::CastKind CastKind = CastExpr::CK_Unknown;        bool IsCopy = false; -      if (CXXConstructorDecl *Constructor -                              = dyn_cast<CXXConstructorDecl>(Step->Function)) { +      FunctionDecl *Fn = cast<FunctionDecl>(Step->Function.getDecl()); +      AccessSpecifier FnAccess = Step->Function.getAccess(); +      if (CXXConstructorDecl *Constructor = dyn_cast<CXXConstructorDecl>(Fn)) {          // Build a call to the selected constructor.          ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);          SourceLocation Loc = CurInitExpr->getLocStart();          CurInit.release(); // Ownership transferred into MultiExprArg, below. -         +          // Determine the arguments required to actually perform the constructor          // call.          if (S.CompleteConstructorCall(Constructor, @@ -3350,6 +3358,8 @@ InitializationSequence::Perform(Sema &S,                                            move_arg(ConstructorArgs));          if (CurInit.isInvalid())            return S.ExprError(); + +        S.CheckConstructorAccess(Kind.getLocation(), Constructor, FnAccess);          CastKind = CastExpr::CK_ConstructorConversion;          QualType Class = S.Context.getTypeDeclType(Constructor->getParent()); @@ -3358,8 +3368,11 @@ InitializationSequence::Perform(Sema &S,            IsCopy = true;        } else {          // Build a call to the conversion function. -        CXXConversionDecl *Conversion = cast<CXXConversionDecl>(Step->Function); +        CXXConversionDecl *Conversion = cast<CXXConversionDecl>(Fn); +        S.CheckMemberOperatorAccess(Kind.getLocation(), CurInitExpr, +                                    Conversion, FnAccess); +                  // FIXME: Should we move this initialization into a separate           // derived-to-base conversion? I believe the answer is "no", because          // we don't want to turn off access control here for c-style casts. @@ -3424,8 +3437,8 @@ InitializationSequence::Perform(Sema &S,      case SK_ConstructorInitialization: {        CXXConstructorDecl *Constructor -        = cast<CXXConstructorDecl>(Step->Function); -       +        = cast<CXXConstructorDecl>(Step->Function.getDecl()); +        // Build a call to the selected constructor.        ASTOwningVector<&ActionBase::DeleteExpr> ConstructorArgs(S);        SourceLocation Loc = Kind.getLocation(); @@ -3444,6 +3457,9 @@ InitializationSequence::Perform(Sema &S,                                 Entity.getKind() == InitializedEntity::EK_Base);        if (CurInit.isInvalid())          return S.ExprError(); + +      // Only check access if all of that succeeded. +      S.CheckConstructorAccess(Loc, Constructor, Step->Function.getAccess());        bool Elidable           = cast<CXXConstructExpr>((Expr *)CurInit.get())->isElidable(); diff --git a/clang/lib/Sema/SemaInit.h b/clang/lib/Sema/SemaInit.h index 001ba91d546..2b49df28fe8 100644 --- a/clang/lib/Sema/SemaInit.h +++ b/clang/lib/Sema/SemaInit.h @@ -15,6 +15,7 @@  #include "SemaOverload.h"  #include "clang/AST/Type.h" +#include "clang/AST/UnresolvedSet.h"  #include "clang/Parse/Action.h"  #include "clang/Basic/SourceLocation.h"  #include "llvm/ADT/PointerIntPair.h" @@ -449,7 +450,11 @@ public:        /// \brief When Kind == SK_ResolvedOverloadedFunction or Kind ==        /// SK_UserConversion, the function that the expression should be         /// resolved to or the conversion function to call, respectively. -      FunctionDecl *Function; +      /// +      /// Always a FunctionDecl. +      /// For conversion decls, the naming class is the source type. +      /// For construct decls, the naming class is the target type. +      DeclAccessPair Function;        /// \brief When Kind = SK_ConversionSequence, the implicit conversion        /// sequence  @@ -616,7 +621,9 @@ public:    /// \brief Add a new step invoking a conversion function, which is either    /// a constructor or a conversion function. -  void AddUserConversionStep(FunctionDecl *Function, QualType T); +  void AddUserConversionStep(FunctionDecl *Function, +                             AccessSpecifier Access, +                             QualType T);    /// \brief Add a new step that performs a qualification conversion to the    /// given type. @@ -631,6 +638,7 @@ public:    /// \brief Add a constructor-initialization step.    void AddConstructorInitializationStep(CXXConstructorDecl *Constructor, +                                        AccessSpecifier Access,                                          QualType T);    /// \brief Add a zero-initialization step.  | 

