Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/clang/lib/Sema/SemaAccess.cpp
Line
Count
Source (jump to first uncovered line)
1
//===---- SemaAccess.cpp - C++ Access Control -------------------*- C++ -*-===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// This file provides Sema routines for C++ access control semantics.
10
//
11
//===----------------------------------------------------------------------===//
12
13
#include "clang/Basic/Specifiers.h"
14
#include "clang/Sema/SemaInternal.h"
15
#include "clang/AST/ASTContext.h"
16
#include "clang/AST/CXXInheritance.h"
17
#include "clang/AST/DeclCXX.h"
18
#include "clang/AST/DeclFriend.h"
19
#include "clang/AST/DeclObjC.h"
20
#include "clang/AST/DependentDiagnostic.h"
21
#include "clang/AST/ExprCXX.h"
22
#include "clang/Sema/DelayedDiagnostic.h"
23
#include "clang/Sema/Initialization.h"
24
#include "clang/Sema/Lookup.h"
25
26
using namespace clang;
27
using namespace sema;
28
29
/// A copy of Sema's enum without AR_delayed.
30
enum AccessResult {
31
  AR_accessible,
32
  AR_inaccessible,
33
  AR_dependent
34
};
35
36
/// SetMemberAccessSpecifier - Set the access specifier of a member.
37
/// Returns true on error (when the previous member decl access specifier
38
/// is different from the new member decl access specifier).
39
bool Sema::SetMemberAccessSpecifier(NamedDecl *MemberDecl,
40
                                    NamedDecl *PrevMemberDecl,
41
0
                                    AccessSpecifier LexicalAS) {
42
0
  if (!PrevMemberDecl) {
43
    // Use the lexical access specifier.
44
0
    MemberDecl->setAccess(LexicalAS);
45
0
    return false;
46
0
  }
47
48
  // C++ [class.access.spec]p3: When a member is redeclared its access
49
  // specifier must be same as its initial declaration.
50
0
  if (LexicalAS != AS_none && LexicalAS != PrevMemberDecl->getAccess()) {
51
0
    Diag(MemberDecl->getLocation(),
52
0
         diag::err_class_redeclared_with_different_access)
53
0
      << MemberDecl << LexicalAS;
54
0
    Diag(PrevMemberDecl->getLocation(), diag::note_previous_access_declaration)
55
0
      << PrevMemberDecl << PrevMemberDecl->getAccess();
56
57
0
    MemberDecl->setAccess(LexicalAS);
58
0
    return true;
59
0
  }
60
61
0
  MemberDecl->setAccess(PrevMemberDecl->getAccess());
62
0
  return false;
63
0
}
64
65
0
static CXXRecordDecl *FindDeclaringClass(NamedDecl *D) {
66
0
  DeclContext *DC = D->getDeclContext();
67
68
  // This can only happen at top: enum decls only "publish" their
69
  // immediate members.
70
0
  if (isa<EnumDecl>(DC))
71
0
    DC = cast<EnumDecl>(DC)->getDeclContext();
72
73
0
  CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC);
74
0
  while (DeclaringClass->isAnonymousStructOrUnion())
75
0
    DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext());
76
0
  return DeclaringClass;
77
0
}
78
79
namespace {
80
struct EffectiveContext {
81
0
  EffectiveContext() : Inner(nullptr), Dependent(false) {}
82
83
  explicit EffectiveContext(DeclContext *DC)
84
    : Inner(DC),
85
0
      Dependent(DC->isDependentContext()) {
86
87
    // An implicit deduction guide is semantically in the context enclosing the
88
    // class template, but for access purposes behaves like the constructor
89
    // from which it was produced.
90
0
    if (auto *DGD = dyn_cast<CXXDeductionGuideDecl>(DC)) {
91
0
      if (DGD->isImplicit()) {
92
0
        DC = DGD->getCorrespondingConstructor();
93
0
        if (!DC) {
94
          // The copy deduction candidate doesn't have a corresponding
95
          // constructor.
96
0
          DC = cast<DeclContext>(DGD->getDeducedTemplate()->getTemplatedDecl());
97
0
        }
98
0
      }
99
0
    }
100
101
    // C++11 [class.access.nest]p1:
102
    //   A nested class is a member and as such has the same access
103
    //   rights as any other member.
104
    // C++11 [class.access]p2:
105
    //   A member of a class can also access all the names to which
106
    //   the class has access.  A local class of a member function
107
    //   may access the same names that the member function itself
108
    //   may access.
109
    // This almost implies that the privileges of nesting are transitive.
110
    // Technically it says nothing about the local classes of non-member
111
    // functions (which can gain privileges through friendship), but we
112
    // take that as an oversight.
113
0
    while (true) {
114
      // We want to add canonical declarations to the EC lists for
115
      // simplicity of checking, but we need to walk up through the
116
      // actual current DC chain.  Otherwise, something like a local
117
      // extern or friend which happens to be the canonical
118
      // declaration will really mess us up.
119
120
0
      if (isa<CXXRecordDecl>(DC)) {
121
0
        CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
122
0
        Records.push_back(Record->getCanonicalDecl());
123
0
        DC = Record->getDeclContext();
124
0
      } else if (isa<FunctionDecl>(DC)) {
125
0
        FunctionDecl *Function = cast<FunctionDecl>(DC);
126
0
        Functions.push_back(Function->getCanonicalDecl());
127
0
        if (Function->getFriendObjectKind())
128
0
          DC = Function->getLexicalDeclContext();
129
0
        else
130
0
          DC = Function->getDeclContext();
131
0
      } else if (DC->isFileContext()) {
132
0
        break;
133
0
      } else {
134
0
        DC = DC->getParent();
135
0
      }
136
0
    }
137
0
  }
138
139
0
  bool isDependent() const { return Dependent; }
140
141
0
  bool includesClass(const CXXRecordDecl *R) const {
142
0
    R = R->getCanonicalDecl();
143
0
    return llvm::is_contained(Records, R);
144
0
  }
145
146
  /// Retrieves the innermost "useful" context.  Can be null if we're
147
  /// doing access-control without privileges.
148
0
  DeclContext *getInnerContext() const {
149
0
    return Inner;
150
0
  }
151
152
  typedef SmallVectorImpl<CXXRecordDecl*>::const_iterator record_iterator;
153
154
  DeclContext *Inner;
155
  SmallVector<FunctionDecl*, 4> Functions;
156
  SmallVector<CXXRecordDecl*, 4> Records;
157
  bool Dependent;
158
};
159
160
/// Like sema::AccessedEntity, but kindly lets us scribble all over
161
/// it.
162
struct AccessTarget : public AccessedEntity {
163
  AccessTarget(const AccessedEntity &Entity)
164
0
    : AccessedEntity(Entity) {
165
0
    initialize();
166
0
  }
167
168
  AccessTarget(ASTContext &Context,
169
               MemberNonce _,
170
               CXXRecordDecl *NamingClass,
171
               DeclAccessPair FoundDecl,
172
               QualType BaseObjectType)
173
    : AccessedEntity(Context.getDiagAllocator(), Member, NamingClass,
174
0
                     FoundDecl, BaseObjectType) {
175
0
    initialize();
176
0
  }
177
178
  AccessTarget(ASTContext &Context,
179
               BaseNonce _,
180
               CXXRecordDecl *BaseClass,
181
               CXXRecordDecl *DerivedClass,
182
               AccessSpecifier Access)
183
    : AccessedEntity(Context.getDiagAllocator(), Base, BaseClass, DerivedClass,
184
0
                     Access) {
185
0
    initialize();
186
0
  }
187
188
0
  bool isInstanceMember() const {
189
0
    return (isMemberAccess() && getTargetDecl()->isCXXInstanceMember());
190
0
  }
191
192
0
  bool hasInstanceContext() const {
193
0
    return HasInstanceContext;
194
0
  }
195
196
  class SavedInstanceContext {
197
  public:
198
    SavedInstanceContext(SavedInstanceContext &&S)
199
0
        : Target(S.Target), Has(S.Has) {
200
0
      S.Target = nullptr;
201
0
    }
202
203
    // The move assignment operator is defined as deleted pending further
204
    // motivation.
205
    SavedInstanceContext &operator=(SavedInstanceContext &&) = delete;
206
207
    // The copy constrcutor and copy assignment operator is defined as deleted
208
    // pending further motivation.
209
    SavedInstanceContext(const SavedInstanceContext &) = delete;
210
    SavedInstanceContext &operator=(const SavedInstanceContext &) = delete;
211
212
0
    ~SavedInstanceContext() {
213
0
      if (Target)
214
0
        Target->HasInstanceContext = Has;
215
0
    }
216
217
  private:
218
    friend struct AccessTarget;
219
    explicit SavedInstanceContext(AccessTarget &Target)
220
0
        : Target(&Target), Has(Target.HasInstanceContext) {}
221
    AccessTarget *Target;
222
    bool Has;
223
  };
224
225
0
  SavedInstanceContext saveInstanceContext() {
226
0
    return SavedInstanceContext(*this);
227
0
  }
228
229
0
  void suppressInstanceContext() {
230
0
    HasInstanceContext = false;
231
0
  }
232
233
0
  const CXXRecordDecl *resolveInstanceContext(Sema &S) const {
234
0
    assert(HasInstanceContext);
235
0
    if (CalculatedInstanceContext)
236
0
      return InstanceContext;
237
238
0
    CalculatedInstanceContext = true;
239
0
    DeclContext *IC = S.computeDeclContext(getBaseObjectType());
240
0
    InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl()
241
0
                          : nullptr);
242
0
    return InstanceContext;
243
0
  }
244
245
0
  const CXXRecordDecl *getDeclaringClass() const {
246
0
    return DeclaringClass;
247
0
  }
248
249
  /// The "effective" naming class is the canonical non-anonymous
250
  /// class containing the actual naming class.
251
0
  const CXXRecordDecl *getEffectiveNamingClass() const {
252
0
    const CXXRecordDecl *namingClass = getNamingClass();
253
0
    while (namingClass->isAnonymousStructOrUnion())
254
0
      namingClass = cast<CXXRecordDecl>(namingClass->getParent());
255
0
    return namingClass->getCanonicalDecl();
256
0
  }
257
258
private:
259
0
  void initialize() {
260
0
    HasInstanceContext = (isMemberAccess() &&
261
0
                          !getBaseObjectType().isNull() &&
262
0
                          getTargetDecl()->isCXXInstanceMember());
263
0
    CalculatedInstanceContext = false;
264
0
    InstanceContext = nullptr;
265
266
0
    if (isMemberAccess())
267
0
      DeclaringClass = FindDeclaringClass(getTargetDecl());
268
0
    else
269
0
      DeclaringClass = getBaseClass();
270
0
    DeclaringClass = DeclaringClass->getCanonicalDecl();
271
0
  }
272
273
  bool HasInstanceContext : 1;
274
  mutable bool CalculatedInstanceContext : 1;
275
  mutable const CXXRecordDecl *InstanceContext;
276
  const CXXRecordDecl *DeclaringClass;
277
};
278
279
}
280
281
/// Checks whether one class might instantiate to the other.
282
static bool MightInstantiateTo(const CXXRecordDecl *From,
283
0
                               const CXXRecordDecl *To) {
284
  // Declaration names are always preserved by instantiation.
285
0
  if (From->getDeclName() != To->getDeclName())
286
0
    return false;
287
288
0
  const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext();
289
0
  const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext();
290
0
  if (FromDC == ToDC) return true;
291
0
  if (FromDC->isFileContext() || ToDC->isFileContext()) return false;
292
293
  // Be conservative.
294
0
  return true;
295
0
}
296
297
/// Checks whether one class is derived from another, inclusively.
298
/// Properly indicates when it couldn't be determined due to
299
/// dependence.
300
///
301
/// This should probably be donated to AST or at least Sema.
302
static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived,
303
0
                                           const CXXRecordDecl *Target) {
304
0
  assert(Derived->getCanonicalDecl() == Derived);
305
0
  assert(Target->getCanonicalDecl() == Target);
306
307
0
  if (Derived == Target) return AR_accessible;
308
309
0
  bool CheckDependent = Derived->isDependentContext();
310
0
  if (CheckDependent && MightInstantiateTo(Derived, Target))
311
0
    return AR_dependent;
312
313
0
  AccessResult OnFailure = AR_inaccessible;
314
0
  SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack
315
316
0
  while (true) {
317
0
    if (Derived->isDependentContext() && !Derived->hasDefinition() &&
318
0
        !Derived->isLambda())
319
0
      return AR_dependent;
320
321
0
    for (const auto &I : Derived->bases()) {
322
0
      const CXXRecordDecl *RD;
323
324
0
      QualType T = I.getType();
325
0
      if (const RecordType *RT = T->getAs<RecordType>()) {
326
0
        RD = cast<CXXRecordDecl>(RT->getDecl());
327
0
      } else if (const InjectedClassNameType *IT
328
0
                   = T->getAs<InjectedClassNameType>()) {
329
0
        RD = IT->getDecl();
330
0
      } else {
331
0
        assert(T->isDependentType() && "non-dependent base wasn't a record?");
332
0
        OnFailure = AR_dependent;
333
0
        continue;
334
0
      }
335
336
0
      RD = RD->getCanonicalDecl();
337
0
      if (RD == Target) return AR_accessible;
338
0
      if (CheckDependent && MightInstantiateTo(RD, Target))
339
0
        OnFailure = AR_dependent;
340
341
0
      Queue.push_back(RD);
342
0
    }
343
344
0
    if (Queue.empty()) break;
345
346
0
    Derived = Queue.pop_back_val();
347
0
  }
348
349
0
  return OnFailure;
350
0
}
351
352
353
static bool MightInstantiateTo(Sema &S, DeclContext *Context,
354
0
                               DeclContext *Friend) {
355
0
  if (Friend == Context)
356
0
    return true;
357
358
0
  assert(!Friend->isDependentContext() &&
359
0
         "can't handle friends with dependent contexts here");
360
361
0
  if (!Context->isDependentContext())
362
0
    return false;
363
364
0
  if (Friend->isFileContext())
365
0
    return false;
366
367
  // TODO: this is very conservative
368
0
  return true;
369
0
}
370
371
// Asks whether the type in 'context' can ever instantiate to the type
372
// in 'friend'.
373
0
static bool MightInstantiateTo(Sema &S, CanQualType Context, CanQualType Friend) {
374
0
  if (Friend == Context)
375
0
    return true;
376
377
0
  if (!Friend->isDependentType() && !Context->isDependentType())
378
0
    return false;
379
380
  // TODO: this is very conservative.
381
0
  return true;
382
0
}
383
384
static bool MightInstantiateTo(Sema &S,
385
                               FunctionDecl *Context,
386
0
                               FunctionDecl *Friend) {
387
0
  if (Context->getDeclName() != Friend->getDeclName())
388
0
    return false;
389
390
0
  if (!MightInstantiateTo(S,
391
0
                          Context->getDeclContext(),
392
0
                          Friend->getDeclContext()))
393
0
    return false;
394
395
0
  CanQual<FunctionProtoType> FriendTy
396
0
    = S.Context.getCanonicalType(Friend->getType())
397
0
         ->getAs<FunctionProtoType>();
398
0
  CanQual<FunctionProtoType> ContextTy
399
0
    = S.Context.getCanonicalType(Context->getType())
400
0
         ->getAs<FunctionProtoType>();
401
402
  // There isn't any way that I know of to add qualifiers
403
  // during instantiation.
404
0
  if (FriendTy.getQualifiers() != ContextTy.getQualifiers())
405
0
    return false;
406
407
0
  if (FriendTy->getNumParams() != ContextTy->getNumParams())
408
0
    return false;
409
410
0
  if (!MightInstantiateTo(S, ContextTy->getReturnType(),
411
0
                          FriendTy->getReturnType()))
412
0
    return false;
413
414
0
  for (unsigned I = 0, E = FriendTy->getNumParams(); I != E; ++I)
415
0
    if (!MightInstantiateTo(S, ContextTy->getParamType(I),
416
0
                            FriendTy->getParamType(I)))
417
0
      return false;
418
419
0
  return true;
420
0
}
421
422
static bool MightInstantiateTo(Sema &S,
423
                               FunctionTemplateDecl *Context,
424
0
                               FunctionTemplateDecl *Friend) {
425
0
  return MightInstantiateTo(S,
426
0
                            Context->getTemplatedDecl(),
427
0
                            Friend->getTemplatedDecl());
428
0
}
429
430
static AccessResult MatchesFriend(Sema &S,
431
                                  const EffectiveContext &EC,
432
0
                                  const CXXRecordDecl *Friend) {
433
0
  if (EC.includesClass(Friend))
434
0
    return AR_accessible;
435
436
0
  if (EC.isDependent()) {
437
0
    for (const CXXRecordDecl *Context : EC.Records) {
438
0
      if (MightInstantiateTo(Context, Friend))
439
0
        return AR_dependent;
440
0
    }
441
0
  }
442
443
0
  return AR_inaccessible;
444
0
}
445
446
static AccessResult MatchesFriend(Sema &S,
447
                                  const EffectiveContext &EC,
448
0
                                  CanQualType Friend) {
449
0
  if (const RecordType *RT = Friend->getAs<RecordType>())
450
0
    return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
451
452
  // TODO: we can do better than this
453
0
  if (Friend->isDependentType())
454
0
    return AR_dependent;
455
456
0
  return AR_inaccessible;
457
0
}
458
459
/// Determines whether the given friend class template matches
460
/// anything in the effective context.
461
static AccessResult MatchesFriend(Sema &S,
462
                                  const EffectiveContext &EC,
463
0
                                  ClassTemplateDecl *Friend) {
464
0
  AccessResult OnFailure = AR_inaccessible;
465
466
  // Check whether the friend is the template of a class in the
467
  // context chain.
468
0
  for (SmallVectorImpl<CXXRecordDecl*>::const_iterator
469
0
         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
470
0
    CXXRecordDecl *Record = *I;
471
472
    // Figure out whether the current class has a template:
473
0
    ClassTemplateDecl *CTD;
474
475
    // A specialization of the template...
476
0
    if (isa<ClassTemplateSpecializationDecl>(Record)) {
477
0
      CTD = cast<ClassTemplateSpecializationDecl>(Record)
478
0
        ->getSpecializedTemplate();
479
480
    // ... or the template pattern itself.
481
0
    } else {
482
0
      CTD = Record->getDescribedClassTemplate();
483
0
      if (!CTD) continue;
484
0
    }
485
486
    // It's a match.
487
0
    if (Friend == CTD->getCanonicalDecl())
488
0
      return AR_accessible;
489
490
    // If the context isn't dependent, it can't be a dependent match.
491
0
    if (!EC.isDependent())
492
0
      continue;
493
494
    // If the template names don't match, it can't be a dependent
495
    // match.
496
0
    if (CTD->getDeclName() != Friend->getDeclName())
497
0
      continue;
498
499
    // If the class's context can't instantiate to the friend's
500
    // context, it can't be a dependent match.
501
0
    if (!MightInstantiateTo(S, CTD->getDeclContext(),
502
0
                            Friend->getDeclContext()))
503
0
      continue;
504
505
    // Otherwise, it's a dependent match.
506
0
    OnFailure = AR_dependent;
507
0
  }
508
509
0
  return OnFailure;
510
0
}
511
512
/// Determines whether the given friend function matches anything in
513
/// the effective context.
514
static AccessResult MatchesFriend(Sema &S,
515
                                  const EffectiveContext &EC,
516
0
                                  FunctionDecl *Friend) {
517
0
  AccessResult OnFailure = AR_inaccessible;
518
519
0
  for (SmallVectorImpl<FunctionDecl*>::const_iterator
520
0
         I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
521
0
    if (Friend == *I)
522
0
      return AR_accessible;
523
524
0
    if (EC.isDependent() && MightInstantiateTo(S, *I, Friend))
525
0
      OnFailure = AR_dependent;
526
0
  }
527
528
0
  return OnFailure;
529
0
}
530
531
/// Determines whether the given friend function template matches
532
/// anything in the effective context.
533
static AccessResult MatchesFriend(Sema &S,
534
                                  const EffectiveContext &EC,
535
0
                                  FunctionTemplateDecl *Friend) {
536
0
  if (EC.Functions.empty()) return AR_inaccessible;
537
538
0
  AccessResult OnFailure = AR_inaccessible;
539
540
0
  for (SmallVectorImpl<FunctionDecl*>::const_iterator
541
0
         I = EC.Functions.begin(), E = EC.Functions.end(); I != E; ++I) {
542
543
0
    FunctionTemplateDecl *FTD = (*I)->getPrimaryTemplate();
544
0
    if (!FTD)
545
0
      FTD = (*I)->getDescribedFunctionTemplate();
546
0
    if (!FTD)
547
0
      continue;
548
549
0
    FTD = FTD->getCanonicalDecl();
550
551
0
    if (Friend == FTD)
552
0
      return AR_accessible;
553
554
0
    if (EC.isDependent() && MightInstantiateTo(S, FTD, Friend))
555
0
      OnFailure = AR_dependent;
556
0
  }
557
558
0
  return OnFailure;
559
0
}
560
561
/// Determines whether the given friend declaration matches anything
562
/// in the effective context.
563
static AccessResult MatchesFriend(Sema &S,
564
                                  const EffectiveContext &EC,
565
0
                                  FriendDecl *FriendD) {
566
  // Whitelist accesses if there's an invalid or unsupported friend
567
  // declaration.
568
0
  if (FriendD->isInvalidDecl() || FriendD->isUnsupportedFriend())
569
0
    return AR_accessible;
570
571
0
  if (TypeSourceInfo *T = FriendD->getFriendType())
572
0
    return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
573
574
0
  NamedDecl *Friend
575
0
    = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl());
576
577
  // FIXME: declarations with dependent or templated scope.
578
579
0
  if (isa<ClassTemplateDecl>(Friend))
580
0
    return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
581
582
0
  if (isa<FunctionTemplateDecl>(Friend))
583
0
    return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
584
585
0
  if (isa<CXXRecordDecl>(Friend))
586
0
    return MatchesFriend(S, EC, cast<CXXRecordDecl>(Friend));
587
588
0
  assert(isa<FunctionDecl>(Friend) && "unknown friend decl kind");
589
0
  return MatchesFriend(S, EC, cast<FunctionDecl>(Friend));
590
0
}
591
592
static AccessResult GetFriendKind(Sema &S,
593
                                  const EffectiveContext &EC,
594
0
                                  const CXXRecordDecl *Class) {
595
0
  AccessResult OnFailure = AR_inaccessible;
596
597
  // Okay, check friends.
598
0
  for (auto *Friend : Class->friends()) {
599
0
    switch (MatchesFriend(S, EC, Friend)) {
600
0
    case AR_accessible:
601
0
      return AR_accessible;
602
603
0
    case AR_inaccessible:
604
0
      continue;
605
606
0
    case AR_dependent:
607
0
      OnFailure = AR_dependent;
608
0
      break;
609
0
    }
610
0
  }
611
612
  // That's it, give up.
613
0
  return OnFailure;
614
0
}
615
616
namespace {
617
618
/// A helper class for checking for a friend which will grant access
619
/// to a protected instance member.
620
struct ProtectedFriendContext {
621
  Sema &S;
622
  const EffectiveContext &EC;
623
  const CXXRecordDecl *NamingClass;
624
  bool CheckDependent;
625
  bool EverDependent;
626
627
  /// The path down to the current base class.
628
  SmallVector<const CXXRecordDecl*, 20> CurPath;
629
630
  ProtectedFriendContext(Sema &S, const EffectiveContext &EC,
631
                         const CXXRecordDecl *InstanceContext,
632
                         const CXXRecordDecl *NamingClass)
633
    : S(S), EC(EC), NamingClass(NamingClass),
634
      CheckDependent(InstanceContext->isDependentContext() ||
635
                     NamingClass->isDependentContext()),
636
0
      EverDependent(false) {}
637
638
  /// Check classes in the current path for friendship, starting at
639
  /// the given index.
640
0
  bool checkFriendshipAlongPath(unsigned I) {
641
0
    assert(I < CurPath.size());
642
0
    for (unsigned E = CurPath.size(); I != E; ++I) {
643
0
      switch (GetFriendKind(S, EC, CurPath[I])) {
644
0
      case AR_accessible:   return true;
645
0
      case AR_inaccessible: continue;
646
0
      case AR_dependent:    EverDependent = true; continue;
647
0
      }
648
0
    }
649
0
    return false;
650
0
  }
651
652
  /// Perform a search starting at the given class.
653
  ///
654
  /// PrivateDepth is the index of the last (least derived) class
655
  /// along the current path such that a notional public member of
656
  /// the final class in the path would have access in that class.
657
0
  bool findFriendship(const CXXRecordDecl *Cur, unsigned PrivateDepth) {
658
    // If we ever reach the naming class, check the current path for
659
    // friendship.  We can also stop recursing because we obviously
660
    // won't find the naming class there again.
661
0
    if (Cur == NamingClass)
662
0
      return checkFriendshipAlongPath(PrivateDepth);
663
664
0
    if (CheckDependent && MightInstantiateTo(Cur, NamingClass))
665
0
      EverDependent = true;
666
667
    // Recurse into the base classes.
668
0
    for (const auto &I : Cur->bases()) {
669
      // If this is private inheritance, then a public member of the
670
      // base will not have any access in classes derived from Cur.
671
0
      unsigned BasePrivateDepth = PrivateDepth;
672
0
      if (I.getAccessSpecifier() == AS_private)
673
0
        BasePrivateDepth = CurPath.size() - 1;
674
675
0
      const CXXRecordDecl *RD;
676
677
0
      QualType T = I.getType();
678
0
      if (const RecordType *RT = T->getAs<RecordType>()) {
679
0
        RD = cast<CXXRecordDecl>(RT->getDecl());
680
0
      } else if (const InjectedClassNameType *IT
681
0
                   = T->getAs<InjectedClassNameType>()) {
682
0
        RD = IT->getDecl();
683
0
      } else {
684
0
        assert(T->isDependentType() && "non-dependent base wasn't a record?");
685
0
        EverDependent = true;
686
0
        continue;
687
0
      }
688
689
      // Recurse.  We don't need to clean up if this returns true.
690
0
      CurPath.push_back(RD);
691
0
      if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth))
692
0
        return true;
693
0
      CurPath.pop_back();
694
0
    }
695
696
0
    return false;
697
0
  }
698
699
0
  bool findFriendship(const CXXRecordDecl *Cur) {
700
0
    assert(CurPath.empty());
701
0
    CurPath.push_back(Cur);
702
0
    return findFriendship(Cur, 0);
703
0
  }
704
};
705
}
706
707
/// Search for a class P that EC is a friend of, under the constraint
708
///   InstanceContext <= P
709
/// if InstanceContext exists, or else
710
///   NamingClass <= P
711
/// and with the additional restriction that a protected member of
712
/// NamingClass would have some natural access in P, which implicitly
713
/// imposes the constraint that P <= NamingClass.
714
///
715
/// This isn't quite the condition laid out in the standard.
716
/// Instead of saying that a notional protected member of NamingClass
717
/// would have to have some natural access in P, it says the actual
718
/// target has to have some natural access in P, which opens up the
719
/// possibility that the target (which is not necessarily a member
720
/// of NamingClass) might be more accessible along some path not
721
/// passing through it.  That's really a bad idea, though, because it
722
/// introduces two problems:
723
///   - Most importantly, it breaks encapsulation because you can
724
///     access a forbidden base class's members by directly subclassing
725
///     it elsewhere.
726
///   - It also makes access substantially harder to compute because it
727
///     breaks the hill-climbing algorithm: knowing that the target is
728
///     accessible in some base class would no longer let you change
729
///     the question solely to whether the base class is accessible,
730
///     because the original target might have been more accessible
731
///     because of crazy subclassing.
732
/// So we don't implement that.
733
static AccessResult GetProtectedFriendKind(Sema &S, const EffectiveContext &EC,
734
                                           const CXXRecordDecl *InstanceContext,
735
0
                                           const CXXRecordDecl *NamingClass) {
736
0
  assert(InstanceContext == nullptr ||
737
0
         InstanceContext->getCanonicalDecl() == InstanceContext);
738
0
  assert(NamingClass->getCanonicalDecl() == NamingClass);
739
740
  // If we don't have an instance context, our constraints give us
741
  // that NamingClass <= P <= NamingClass, i.e. P == NamingClass.
742
  // This is just the usual friendship check.
743
0
  if (!InstanceContext) return GetFriendKind(S, EC, NamingClass);
744
745
0
  ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
746
0
  if (PRC.findFriendship(InstanceContext)) return AR_accessible;
747
0
  if (PRC.EverDependent) return AR_dependent;
748
0
  return AR_inaccessible;
749
0
}
750
751
static AccessResult HasAccess(Sema &S,
752
                              const EffectiveContext &EC,
753
                              const CXXRecordDecl *NamingClass,
754
                              AccessSpecifier Access,
755
0
                              const AccessTarget &Target) {
756
0
  assert(NamingClass->getCanonicalDecl() == NamingClass &&
757
0
         "declaration should be canonicalized before being passed here");
758
759
0
  if (Access == AS_public) return AR_accessible;
760
0
  assert(Access == AS_private || Access == AS_protected);
761
762
0
  AccessResult OnFailure = AR_inaccessible;
763
764
0
  for (EffectiveContext::record_iterator
765
0
         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
766
    // All the declarations in EC have been canonicalized, so pointer
767
    // equality from this point on will work fine.
768
0
    const CXXRecordDecl *ECRecord = *I;
769
770
    // [B2] and [M2]
771
0
    if (Access == AS_private) {
772
0
      if (ECRecord == NamingClass)
773
0
        return AR_accessible;
774
775
0
      if (EC.isDependent() && MightInstantiateTo(ECRecord, NamingClass))
776
0
        OnFailure = AR_dependent;
777
778
    // [B3] and [M3]
779
0
    } else {
780
0
      assert(Access == AS_protected);
781
0
      switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
782
0
      case AR_accessible: break;
783
0
      case AR_inaccessible: continue;
784
0
      case AR_dependent: OnFailure = AR_dependent; continue;
785
0
      }
786
787
      // C++ [class.protected]p1:
788
      //   An additional access check beyond those described earlier in
789
      //   [class.access] is applied when a non-static data member or
790
      //   non-static member function is a protected member of its naming
791
      //   class.  As described earlier, access to a protected member is
792
      //   granted because the reference occurs in a friend or member of
793
      //   some class C.  If the access is to form a pointer to member,
794
      //   the nested-name-specifier shall name C or a class derived from
795
      //   C. All other accesses involve a (possibly implicit) object
796
      //   expression. In this case, the class of the object expression
797
      //   shall be C or a class derived from C.
798
      //
799
      // We interpret this as a restriction on [M3].
800
801
      // In this part of the code, 'C' is just our context class ECRecord.
802
803
      // These rules are different if we don't have an instance context.
804
0
      if (!Target.hasInstanceContext()) {
805
        // If it's not an instance member, these restrictions don't apply.
806
0
        if (!Target.isInstanceMember()) return AR_accessible;
807
808
        // If it's an instance member, use the pointer-to-member rule
809
        // that the naming class has to be derived from the effective
810
        // context.
811
812
        // Emulate a MSVC bug where the creation of pointer-to-member
813
        // to protected member of base class is allowed but only from
814
        // static member functions.
815
0
        if (S.getLangOpts().MSVCCompat && !EC.Functions.empty())
816
0
          if (CXXMethodDecl* MD = dyn_cast<CXXMethodDecl>(EC.Functions.front()))
817
0
            if (MD->isStatic()) return AR_accessible;
818
819
        // Despite the standard's confident wording, there is a case
820
        // where you can have an instance member that's neither in a
821
        // pointer-to-member expression nor in a member access:  when
822
        // it names a field in an unevaluated context that can't be an
823
        // implicit member.  Pending clarification, we just apply the
824
        // same naming-class restriction here.
825
        //   FIXME: we're probably not correctly adding the
826
        //   protected-member restriction when we retroactively convert
827
        //   an expression to being evaluated.
828
829
        // We know that ECRecord derives from NamingClass.  The
830
        // restriction says to check whether NamingClass derives from
831
        // ECRecord, but that's not really necessary: two distinct
832
        // classes can't be recursively derived from each other.  So
833
        // along this path, we just need to check whether the classes
834
        // are equal.
835
0
        if (NamingClass == ECRecord) return AR_accessible;
836
837
        // Otherwise, this context class tells us nothing;  on to the next.
838
0
        continue;
839
0
      }
840
841
0
      assert(Target.isInstanceMember());
842
843
0
      const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
844
0
      if (!InstanceContext) {
845
0
        OnFailure = AR_dependent;
846
0
        continue;
847
0
      }
848
849
0
      switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
850
0
      case AR_accessible: return AR_accessible;
851
0
      case AR_inaccessible: continue;
852
0
      case AR_dependent: OnFailure = AR_dependent; continue;
853
0
      }
854
0
    }
855
0
  }
856
857
  // [M3] and [B3] say that, if the target is protected in N, we grant
858
  // access if the access occurs in a friend or member of some class P
859
  // that's a subclass of N and where the target has some natural
860
  // access in P.  The 'member' aspect is easy to handle because P
861
  // would necessarily be one of the effective-context records, and we
862
  // address that above.  The 'friend' aspect is completely ridiculous
863
  // to implement because there are no restrictions at all on P
864
  // *unless* the [class.protected] restriction applies.  If it does,
865
  // however, we should ignore whether the naming class is a friend,
866
  // and instead rely on whether any potential P is a friend.
867
0
  if (Access == AS_protected && Target.isInstanceMember()) {
868
    // Compute the instance context if possible.
869
0
    const CXXRecordDecl *InstanceContext = nullptr;
870
0
    if (Target.hasInstanceContext()) {
871
0
      InstanceContext = Target.resolveInstanceContext(S);
872
0
      if (!InstanceContext) return AR_dependent;
873
0
    }
874
875
0
    switch (GetProtectedFriendKind(S, EC, InstanceContext, NamingClass)) {
876
0
    case AR_accessible: return AR_accessible;
877
0
    case AR_inaccessible: return OnFailure;
878
0
    case AR_dependent: return AR_dependent;
879
0
    }
880
0
    llvm_unreachable("impossible friendship kind");
881
0
  }
882
883
0
  switch (GetFriendKind(S, EC, NamingClass)) {
884
0
  case AR_accessible: return AR_accessible;
885
0
  case AR_inaccessible: return OnFailure;
886
0
  case AR_dependent: return AR_dependent;
887
0
  }
888
889
  // Silence bogus warnings
890
0
  llvm_unreachable("impossible friendship kind");
891
0
}
892
893
/// Finds the best path from the naming class to the declaring class,
894
/// taking friend declarations into account.
895
///
896
/// C++0x [class.access.base]p5:
897
///   A member m is accessible at the point R when named in class N if
898
///   [M1] m as a member of N is public, or
899
///   [M2] m as a member of N is private, and R occurs in a member or
900
///        friend of class N, or
901
///   [M3] m as a member of N is protected, and R occurs in a member or
902
///        friend of class N, or in a member or friend of a class P
903
///        derived from N, where m as a member of P is public, private,
904
///        or protected, or
905
///   [M4] there exists a base class B of N that is accessible at R, and
906
///        m is accessible at R when named in class B.
907
///
908
/// C++0x [class.access.base]p4:
909
///   A base class B of N is accessible at R, if
910
///   [B1] an invented public member of B would be a public member of N, or
911
///   [B2] R occurs in a member or friend of class N, and an invented public
912
///        member of B would be a private or protected member of N, or
913
///   [B3] R occurs in a member or friend of a class P derived from N, and an
914
///        invented public member of B would be a private or protected member
915
///        of P, or
916
///   [B4] there exists a class S such that B is a base class of S accessible
917
///        at R and S is a base class of N accessible at R.
918
///
919
/// Along a single inheritance path we can restate both of these
920
/// iteratively:
921
///
922
/// First, we note that M1-4 are equivalent to B1-4 if the member is
923
/// treated as a notional base of its declaring class with inheritance
924
/// access equivalent to the member's access.  Therefore we need only
925
/// ask whether a class B is accessible from a class N in context R.
926
///
927
/// Let B_1 .. B_n be the inheritance path in question (i.e. where
928
/// B_1 = N, B_n = B, and for all i, B_{i+1} is a direct base class of
929
/// B_i).  For i in 1..n, we will calculate ACAB(i), the access to the
930
/// closest accessible base in the path:
931
///   Access(a, b) = (* access on the base specifier from a to b *)
932
///   Merge(a, forbidden) = forbidden
933
///   Merge(a, private) = forbidden
934
///   Merge(a, b) = min(a,b)
935
///   Accessible(c, forbidden) = false
936
///   Accessible(c, private) = (R is c) || IsFriend(c, R)
937
///   Accessible(c, protected) = (R derived from c) || IsFriend(c, R)
938
///   Accessible(c, public) = true
939
///   ACAB(n) = public
940
///   ACAB(i) =
941
///     let AccessToBase = Merge(Access(B_i, B_{i+1}), ACAB(i+1)) in
942
///     if Accessible(B_i, AccessToBase) then public else AccessToBase
943
///
944
/// B is an accessible base of N at R iff ACAB(1) = public.
945
///
946
/// \param FinalAccess the access of the "final step", or AS_public if
947
///   there is no final step.
948
/// \return null if friendship is dependent
949
static CXXBasePath *FindBestPath(Sema &S,
950
                                 const EffectiveContext &EC,
951
                                 AccessTarget &Target,
952
                                 AccessSpecifier FinalAccess,
953
0
                                 CXXBasePaths &Paths) {
954
  // Derive the paths to the desired base.
955
0
  const CXXRecordDecl *Derived = Target.getNamingClass();
956
0
  const CXXRecordDecl *Base = Target.getDeclaringClass();
957
958
  // FIXME: fail correctly when there are dependent paths.
959
0
  bool isDerived = Derived->isDerivedFrom(const_cast<CXXRecordDecl*>(Base),
960
0
                                          Paths);
961
0
  assert(isDerived && "derived class not actually derived from base");
962
0
  (void) isDerived;
963
964
0
  CXXBasePath *BestPath = nullptr;
965
966
0
  assert(FinalAccess != AS_none && "forbidden access after declaring class");
967
968
0
  bool AnyDependent = false;
969
970
  // Derive the friend-modified access along each path.
971
0
  for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end();
972
0
         PI != PE; ++PI) {
973
0
    AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();
974
975
    // Walk through the path backwards.
976
0
    AccessSpecifier PathAccess = FinalAccess;
977
0
    CXXBasePath::iterator I = PI->end(), E = PI->begin();
978
0
    while (I != E) {
979
0
      --I;
980
981
0
      assert(PathAccess != AS_none);
982
983
      // If the declaration is a private member of a base class, there
984
      // is no level of friendship in derived classes that can make it
985
      // accessible.
986
0
      if (PathAccess == AS_private) {
987
0
        PathAccess = AS_none;
988
0
        break;
989
0
      }
990
991
0
      const CXXRecordDecl *NC = I->Class->getCanonicalDecl();
992
993
0
      AccessSpecifier BaseAccess = I->Base->getAccessSpecifier();
994
0
      PathAccess = std::max(PathAccess, BaseAccess);
995
996
0
      switch (HasAccess(S, EC, NC, PathAccess, Target)) {
997
0
      case AR_inaccessible: break;
998
0
      case AR_accessible:
999
0
        PathAccess = AS_public;
1000
1001
        // Future tests are not against members and so do not have
1002
        // instance context.
1003
0
        Target.suppressInstanceContext();
1004
0
        break;
1005
0
      case AR_dependent:
1006
0
        AnyDependent = true;
1007
0
        goto Next;
1008
0
      }
1009
0
    }
1010
1011
    // Note that we modify the path's Access field to the
1012
    // friend-modified access.
1013
0
    if (BestPath == nullptr || PathAccess < BestPath->Access) {
1014
0
      BestPath = &*PI;
1015
0
      BestPath->Access = PathAccess;
1016
1017
      // Short-circuit if we found a public path.
1018
0
      if (BestPath->Access == AS_public)
1019
0
        return BestPath;
1020
0
    }
1021
1022
0
  Next: ;
1023
0
  }
1024
1025
0
  assert((!BestPath || BestPath->Access != AS_public) &&
1026
0
         "fell out of loop with public path");
1027
1028
  // We didn't find a public path, but at least one path was subject
1029
  // to dependent friendship, so delay the check.
1030
0
  if (AnyDependent)
1031
0
    return nullptr;
1032
1033
0
  return BestPath;
1034
0
}
1035
1036
/// Given that an entity has protected natural access, check whether
1037
/// access might be denied because of the protected member access
1038
/// restriction.
1039
///
1040
/// \return true if a note was emitted
1041
static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC,
1042
0
                                       AccessTarget &Target) {
1043
  // Only applies to instance accesses.
1044
0
  if (!Target.isInstanceMember())
1045
0
    return false;
1046
1047
0
  assert(Target.isMemberAccess());
1048
1049
0
  const CXXRecordDecl *NamingClass = Target.getEffectiveNamingClass();
1050
1051
0
  for (EffectiveContext::record_iterator
1052
0
         I = EC.Records.begin(), E = EC.Records.end(); I != E; ++I) {
1053
0
    const CXXRecordDecl *ECRecord = *I;
1054
0
    switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
1055
0
    case AR_accessible: break;
1056
0
    case AR_inaccessible: continue;
1057
0
    case AR_dependent: continue;
1058
0
    }
1059
1060
    // The effective context is a subclass of the declaring class.
1061
    // Check whether the [class.protected] restriction is limiting
1062
    // access.
1063
1064
    // To get this exactly right, this might need to be checked more
1065
    // holistically;  it's not necessarily the case that gaining
1066
    // access here would grant us access overall.
1067
1068
0
    NamedDecl *D = Target.getTargetDecl();
1069
1070
    // If we don't have an instance context, [class.protected] says the
1071
    // naming class has to equal the context class.
1072
0
    if (!Target.hasInstanceContext()) {
1073
      // If it does, the restriction doesn't apply.
1074
0
      if (NamingClass == ECRecord) continue;
1075
1076
      // TODO: it would be great to have a fixit here, since this is
1077
      // such an obvious error.
1078
0
      S.Diag(D->getLocation(), diag::note_access_protected_restricted_noobject)
1079
0
        << S.Context.getTypeDeclType(ECRecord);
1080
0
      return true;
1081
0
    }
1082
1083
0
    const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
1084
0
    assert(InstanceContext && "diagnosing dependent access");
1085
1086
0
    switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
1087
0
    case AR_accessible: continue;
1088
0
    case AR_dependent: continue;
1089
0
    case AR_inaccessible:
1090
0
      break;
1091
0
    }
1092
1093
    // Okay, the restriction seems to be what's limiting us.
1094
1095
    // Use a special diagnostic for constructors and destructors.
1096
0
    if (isa<CXXConstructorDecl>(D) || isa<CXXDestructorDecl>(D) ||
1097
0
        (isa<FunctionTemplateDecl>(D) &&
1098
0
         isa<CXXConstructorDecl>(
1099
0
                cast<FunctionTemplateDecl>(D)->getTemplatedDecl()))) {
1100
0
      return S.Diag(D->getLocation(),
1101
0
                    diag::note_access_protected_restricted_ctordtor)
1102
0
             << isa<CXXDestructorDecl>(D->getAsFunction());
1103
0
    }
1104
1105
    // Otherwise, use the generic diagnostic.
1106
0
    return S.Diag(D->getLocation(),
1107
0
                  diag::note_access_protected_restricted_object)
1108
0
           << S.Context.getTypeDeclType(ECRecord);
1109
0
  }
1110
1111
0
  return false;
1112
0
}
1113
1114
/// We are unable to access a given declaration due to its direct
1115
/// access control;  diagnose that.
1116
static void diagnoseBadDirectAccess(Sema &S,
1117
                                    const EffectiveContext &EC,
1118
0
                                    AccessTarget &entity) {
1119
0
  assert(entity.isMemberAccess());
1120
0
  NamedDecl *D = entity.getTargetDecl();
1121
1122
0
  if (D->getAccess() == AS_protected &&
1123
0
      TryDiagnoseProtectedAccess(S, EC, entity))
1124
0
    return;
1125
1126
  // Find an original declaration.
1127
0
  while (D->isOutOfLine()) {
1128
0
    NamedDecl *PrevDecl = nullptr;
1129
0
    if (VarDecl *VD = dyn_cast<VarDecl>(D))
1130
0
      PrevDecl = VD->getPreviousDecl();
1131
0
    else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D))
1132
0
      PrevDecl = FD->getPreviousDecl();
1133
0
    else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D))
1134
0
      PrevDecl = TND->getPreviousDecl();
1135
0
    else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
1136
0
      if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
1137
0
        break;
1138
0
      PrevDecl = TD->getPreviousDecl();
1139
0
    }
1140
0
    if (!PrevDecl) break;
1141
0
    D = PrevDecl;
1142
0
  }
1143
1144
0
  CXXRecordDecl *DeclaringClass = FindDeclaringClass(D);
1145
0
  Decl *ImmediateChild;
1146
0
  if (D->getDeclContext() == DeclaringClass)
1147
0
    ImmediateChild = D;
1148
0
  else {
1149
0
    DeclContext *DC = D->getDeclContext();
1150
0
    while (DC->getParent() != DeclaringClass)
1151
0
      DC = DC->getParent();
1152
0
    ImmediateChild = cast<Decl>(DC);
1153
0
  }
1154
1155
  // Check whether there's an AccessSpecDecl preceding this in the
1156
  // chain of the DeclContext.
1157
0
  bool isImplicit = true;
1158
0
  for (const auto *I : DeclaringClass->decls()) {
1159
0
    if (I == ImmediateChild) break;
1160
0
    if (isa<AccessSpecDecl>(I)) {
1161
0
      isImplicit = false;
1162
0
      break;
1163
0
    }
1164
0
  }
1165
1166
0
  S.Diag(D->getLocation(), diag::note_access_natural)
1167
0
    << (unsigned) (D->getAccess() == AS_protected)
1168
0
    << isImplicit;
1169
0
}
1170
1171
/// Diagnose the path which caused the given declaration or base class
1172
/// to become inaccessible.
1173
static void DiagnoseAccessPath(Sema &S,
1174
                               const EffectiveContext &EC,
1175
0
                               AccessTarget &entity) {
1176
  // Save the instance context to preserve invariants.
1177
0
  AccessTarget::SavedInstanceContext _ = entity.saveInstanceContext();
1178
1179
  // This basically repeats the main algorithm but keeps some more
1180
  // information.
1181
1182
  // The natural access so far.
1183
0
  AccessSpecifier accessSoFar = AS_public;
1184
1185
  // Check whether we have special rights to the declaring class.
1186
0
  if (entity.isMemberAccess()) {
1187
0
    NamedDecl *D = entity.getTargetDecl();
1188
0
    accessSoFar = D->getAccess();
1189
0
    const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
1190
1191
0
    switch (HasAccess(S, EC, declaringClass, accessSoFar, entity)) {
1192
    // If the declaration is accessible when named in its declaring
1193
    // class, then we must be constrained by the path.
1194
0
    case AR_accessible:
1195
0
      accessSoFar = AS_public;
1196
0
      entity.suppressInstanceContext();
1197
0
      break;
1198
1199
0
    case AR_inaccessible:
1200
0
      if (accessSoFar == AS_private ||
1201
0
          declaringClass == entity.getEffectiveNamingClass())
1202
0
        return diagnoseBadDirectAccess(S, EC, entity);
1203
0
      break;
1204
1205
0
    case AR_dependent:
1206
0
      llvm_unreachable("cannot diagnose dependent access");
1207
0
    }
1208
0
  }
1209
1210
0
  CXXBasePaths paths;
1211
0
  CXXBasePath &path = *FindBestPath(S, EC, entity, accessSoFar, paths);
1212
0
  assert(path.Access != AS_public);
1213
1214
0
  CXXBasePath::iterator i = path.end(), e = path.begin();
1215
0
  CXXBasePath::iterator constrainingBase = i;
1216
0
  while (i != e) {
1217
0
    --i;
1218
1219
0
    assert(accessSoFar != AS_none && accessSoFar != AS_private);
1220
1221
    // Is the entity accessible when named in the deriving class, as
1222
    // modified by the base specifier?
1223
0
    const CXXRecordDecl *derivingClass = i->Class->getCanonicalDecl();
1224
0
    const CXXBaseSpecifier *base = i->Base;
1225
1226
    // If the access to this base is worse than the access we have to
1227
    // the declaration, remember it.
1228
0
    AccessSpecifier baseAccess = base->getAccessSpecifier();
1229
0
    if (baseAccess > accessSoFar) {
1230
0
      constrainingBase = i;
1231
0
      accessSoFar = baseAccess;
1232
0
    }
1233
1234
0
    switch (HasAccess(S, EC, derivingClass, accessSoFar, entity)) {
1235
0
    case AR_inaccessible: break;
1236
0
    case AR_accessible:
1237
0
      accessSoFar = AS_public;
1238
0
      entity.suppressInstanceContext();
1239
0
      constrainingBase = nullptr;
1240
0
      break;
1241
0
    case AR_dependent:
1242
0
      llvm_unreachable("cannot diagnose dependent access");
1243
0
    }
1244
1245
    // If this was private inheritance, but we don't have access to
1246
    // the deriving class, we're done.
1247
0
    if (accessSoFar == AS_private) {
1248
0
      assert(baseAccess == AS_private);
1249
0
      assert(constrainingBase == i);
1250
0
      break;
1251
0
    }
1252
0
  }
1253
1254
  // If we don't have a constraining base, the access failure must be
1255
  // due to the original declaration.
1256
0
  if (constrainingBase == path.end())
1257
0
    return diagnoseBadDirectAccess(S, EC, entity);
1258
1259
  // We're constrained by inheritance, but we want to say
1260
  // "declared private here" if we're diagnosing a hierarchy
1261
  // conversion and this is the final step.
1262
0
  unsigned diagnostic;
1263
0
  if (entity.isMemberAccess() ||
1264
0
      constrainingBase + 1 != path.end()) {
1265
0
    diagnostic = diag::note_access_constrained_by_path;
1266
0
  } else {
1267
0
    diagnostic = diag::note_access_natural;
1268
0
  }
1269
1270
0
  const CXXBaseSpecifier *base = constrainingBase->Base;
1271
1272
0
  S.Diag(base->getSourceRange().getBegin(), diagnostic)
1273
0
    << base->getSourceRange()
1274
0
    << (base->getAccessSpecifier() == AS_protected)
1275
0
    << (base->getAccessSpecifierAsWritten() == AS_none);
1276
1277
0
  if (entity.isMemberAccess())
1278
0
    S.Diag(entity.getTargetDecl()->getLocation(),
1279
0
           diag::note_member_declared_at);
1280
0
}
1281
1282
static void DiagnoseBadAccess(Sema &S, SourceLocation Loc,
1283
                              const EffectiveContext &EC,
1284
0
                              AccessTarget &Entity) {
1285
0
  const CXXRecordDecl *NamingClass = Entity.getNamingClass();
1286
0
  const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1287
0
  NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : nullptr);
1288
1289
0
  S.Diag(Loc, Entity.getDiag())
1290
0
    << (Entity.getAccess() == AS_protected)
1291
0
    << (D ? D->getDeclName() : DeclarationName())
1292
0
    << S.Context.getTypeDeclType(NamingClass)
1293
0
    << S.Context.getTypeDeclType(DeclaringClass);
1294
0
  DiagnoseAccessPath(S, EC, Entity);
1295
0
}
1296
1297
/// MSVC has a bug where if during an using declaration name lookup,
1298
/// the declaration found is unaccessible (private) and that declaration
1299
/// was bring into scope via another using declaration whose target
1300
/// declaration is accessible (public) then no error is generated.
1301
/// Example:
1302
///   class A {
1303
///   public:
1304
///     int f();
1305
///   };
1306
///   class B : public A {
1307
///   private:
1308
///     using A::f;
1309
///   };
1310
///   class C : public B {
1311
///   private:
1312
///     using B::f;
1313
///   };
1314
///
1315
/// Here, B::f is private so this should fail in Standard C++, but
1316
/// because B::f refers to A::f which is public MSVC accepts it.
1317
static bool IsMicrosoftUsingDeclarationAccessBug(Sema& S,
1318
                                                 SourceLocation AccessLoc,
1319
0
                                                 AccessTarget &Entity) {
1320
0
  if (UsingShadowDecl *Shadow =
1321
0
          dyn_cast<UsingShadowDecl>(Entity.getTargetDecl()))
1322
0
    if (UsingDecl *UD = dyn_cast<UsingDecl>(Shadow->getIntroducer())) {
1323
0
      const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();
1324
0
      if (Entity.getTargetDecl()->getAccess() == AS_private &&
1325
0
          (OrigDecl->getAccess() == AS_public ||
1326
0
           OrigDecl->getAccess() == AS_protected)) {
1327
0
        S.Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
1328
0
            << UD->getQualifiedNameAsString()
1329
0
            << OrigDecl->getQualifiedNameAsString();
1330
0
        return true;
1331
0
      }
1332
0
    }
1333
0
  return false;
1334
0
}
1335
1336
/// Determines whether the accessed entity is accessible.  Public members
1337
/// have been weeded out by this point.
1338
static AccessResult IsAccessible(Sema &S,
1339
                                 const EffectiveContext &EC,
1340
0
                                 AccessTarget &Entity) {
1341
  // Determine the actual naming class.
1342
0
  const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
1343
1344
0
  AccessSpecifier UnprivilegedAccess = Entity.getAccess();
1345
0
  assert(UnprivilegedAccess != AS_public && "public access not weeded out");
1346
1347
  // Before we try to recalculate access paths, try to white-list
1348
  // accesses which just trade in on the final step, i.e. accesses
1349
  // which don't require [M4] or [B4]. These are by far the most
1350
  // common forms of privileged access.
1351
0
  if (UnprivilegedAccess != AS_none) {
1352
0
    switch (HasAccess(S, EC, NamingClass, UnprivilegedAccess, Entity)) {
1353
0
    case AR_dependent:
1354
      // This is actually an interesting policy decision.  We don't
1355
      // *have* to delay immediately here: we can do the full access
1356
      // calculation in the hope that friendship on some intermediate
1357
      // class will make the declaration accessible non-dependently.
1358
      // But that's not cheap, and odds are very good (note: assertion
1359
      // made without data) that the friend declaration will determine
1360
      // access.
1361
0
      return AR_dependent;
1362
1363
0
    case AR_accessible: return AR_accessible;
1364
0
    case AR_inaccessible: break;
1365
0
    }
1366
0
  }
1367
1368
0
  AccessTarget::SavedInstanceContext _ = Entity.saveInstanceContext();
1369
1370
  // We lower member accesses to base accesses by pretending that the
1371
  // member is a base class of its declaring class.
1372
0
  AccessSpecifier FinalAccess;
1373
1374
0
  if (Entity.isMemberAccess()) {
1375
    // Determine if the declaration is accessible from EC when named
1376
    // in its declaring class.
1377
0
    NamedDecl *Target = Entity.getTargetDecl();
1378
0
    const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1379
1380
0
    FinalAccess = Target->getAccess();
1381
0
    switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
1382
0
    case AR_accessible:
1383
      // Target is accessible at EC when named in its declaring class.
1384
      // We can now hill-climb and simply check whether the declaring
1385
      // class is accessible as a base of the naming class.  This is
1386
      // equivalent to checking the access of a notional public
1387
      // member with no instance context.
1388
0
      FinalAccess = AS_public;
1389
0
      Entity.suppressInstanceContext();
1390
0
      break;
1391
0
    case AR_inaccessible: break;
1392
0
    case AR_dependent: return AR_dependent; // see above
1393
0
    }
1394
1395
0
    if (DeclaringClass == NamingClass)
1396
0
      return (FinalAccess == AS_public ? AR_accessible : AR_inaccessible);
1397
0
  } else {
1398
0
    FinalAccess = AS_public;
1399
0
  }
1400
1401
0
  assert(Entity.getDeclaringClass() != NamingClass);
1402
1403
  // Append the declaration's access if applicable.
1404
0
  CXXBasePaths Paths;
1405
0
  CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths);
1406
0
  if (!Path)
1407
0
    return AR_dependent;
1408
1409
0
  assert(Path->Access <= UnprivilegedAccess &&
1410
0
         "access along best path worse than direct?");
1411
0
  if (Path->Access == AS_public)
1412
0
    return AR_accessible;
1413
0
  return AR_inaccessible;
1414
0
}
1415
1416
static void DelayDependentAccess(Sema &S,
1417
                                 const EffectiveContext &EC,
1418
                                 SourceLocation Loc,
1419
0
                                 const AccessTarget &Entity) {
1420
0
  assert(EC.isDependent() && "delaying non-dependent access");
1421
0
  DeclContext *DC = EC.getInnerContext();
1422
0
  assert(DC->isDependentContext() && "delaying non-dependent access");
1423
0
  DependentDiagnostic::Create(S.Context, DC, DependentDiagnostic::Access,
1424
0
                              Loc,
1425
0
                              Entity.isMemberAccess(),
1426
0
                              Entity.getAccess(),
1427
0
                              Entity.getTargetDecl(),
1428
0
                              Entity.getNamingClass(),
1429
0
                              Entity.getBaseObjectType(),
1430
0
                              Entity.getDiag());
1431
0
}
1432
1433
/// Checks access to an entity from the given effective context.
1434
static AccessResult CheckEffectiveAccess(Sema &S,
1435
                                         const EffectiveContext &EC,
1436
                                         SourceLocation Loc,
1437
0
                                         AccessTarget &Entity) {
1438
0
  assert(Entity.getAccess() != AS_public && "called for public access!");
1439
1440
0
  switch (IsAccessible(S, EC, Entity)) {
1441
0
  case AR_dependent:
1442
0
    DelayDependentAccess(S, EC, Loc, Entity);
1443
0
    return AR_dependent;
1444
1445
0
  case AR_inaccessible:
1446
0
    if (S.getLangOpts().MSVCCompat &&
1447
0
        IsMicrosoftUsingDeclarationAccessBug(S, Loc, Entity))
1448
0
      return AR_accessible;
1449
0
    if (!Entity.isQuiet())
1450
0
      DiagnoseBadAccess(S, Loc, EC, Entity);
1451
0
    return AR_inaccessible;
1452
1453
0
  case AR_accessible:
1454
0
    return AR_accessible;
1455
0
  }
1456
1457
  // silence unnecessary warning
1458
0
  llvm_unreachable("invalid access result");
1459
0
}
1460
1461
static Sema::AccessResult CheckAccess(Sema &S, SourceLocation Loc,
1462
0
                                      AccessTarget &Entity) {
1463
  // If the access path is public, it's accessible everywhere.
1464
0
  if (Entity.getAccess() == AS_public)
1465
0
    return Sema::AR_accessible;
1466
1467
  // If we're currently parsing a declaration, we may need to delay
1468
  // access control checking, because our effective context might be
1469
  // different based on what the declaration comes out as.
1470
  //
1471
  // For example, we might be parsing a declaration with a scope
1472
  // specifier, like this:
1473
  //   A::private_type A::foo() { ... }
1474
  //
1475
  // Or we might be parsing something that will turn out to be a friend:
1476
  //   void foo(A::private_type);
1477
  //   void B::foo(A::private_type);
1478
0
  if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
1479
0
    S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
1480
0
    return Sema::AR_delayed;
1481
0
  }
1482
1483
0
  EffectiveContext EC(S.CurContext);
1484
0
  switch (CheckEffectiveAccess(S, EC, Loc, Entity)) {
1485
0
  case AR_accessible: return Sema::AR_accessible;
1486
0
  case AR_inaccessible: return Sema::AR_inaccessible;
1487
0
  case AR_dependent: return Sema::AR_dependent;
1488
0
  }
1489
0
  llvm_unreachable("invalid access result");
1490
0
}
1491
1492
0
void Sema::HandleDelayedAccessCheck(DelayedDiagnostic &DD, Decl *D) {
1493
  // Access control for names used in the declarations of functions
1494
  // and function templates should normally be evaluated in the context
1495
  // of the declaration, just in case it's a friend of something.
1496
  // However, this does not apply to local extern declarations.
1497
1498
0
  DeclContext *DC = D->getDeclContext();
1499
0
  if (D->isLocalExternDecl()) {
1500
0
    DC = D->getLexicalDeclContext();
1501
0
  } else if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
1502
0
    DC = FN;
1503
0
  } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
1504
0
    if (isa<DeclContext>(TD->getTemplatedDecl()))
1505
0
      DC = cast<DeclContext>(TD->getTemplatedDecl());
1506
0
  } else if (auto *RD = dyn_cast<RequiresExprBodyDecl>(D)) {
1507
0
    DC = RD;
1508
0
  }
1509
1510
0
  EffectiveContext EC(DC);
1511
1512
0
  AccessTarget Target(DD.getAccessData());
1513
1514
0
  if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible)
1515
0
    DD.Triggered = true;
1516
0
}
1517
1518
void Sema::HandleDependentAccessCheck(const DependentDiagnostic &DD,
1519
0
                        const MultiLevelTemplateArgumentList &TemplateArgs) {
1520
0
  SourceLocation Loc = DD.getAccessLoc();
1521
0
  AccessSpecifier Access = DD.getAccess();
1522
1523
0
  Decl *NamingD = FindInstantiatedDecl(Loc, DD.getAccessNamingClass(),
1524
0
                                       TemplateArgs);
1525
0
  if (!NamingD) return;
1526
0
  Decl *TargetD = FindInstantiatedDecl(Loc, DD.getAccessTarget(),
1527
0
                                       TemplateArgs);
1528
0
  if (!TargetD) return;
1529
1530
0
  if (DD.isAccessToMember()) {
1531
0
    CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(NamingD);
1532
0
    NamedDecl *TargetDecl = cast<NamedDecl>(TargetD);
1533
0
    QualType BaseObjectType = DD.getAccessBaseObjectType();
1534
0
    if (!BaseObjectType.isNull()) {
1535
0
      BaseObjectType = SubstType(BaseObjectType, TemplateArgs, Loc,
1536
0
                                 DeclarationName());
1537
0
      if (BaseObjectType.isNull()) return;
1538
0
    }
1539
1540
0
    AccessTarget Entity(Context,
1541
0
                        AccessTarget::Member,
1542
0
                        NamingClass,
1543
0
                        DeclAccessPair::make(TargetDecl, Access),
1544
0
                        BaseObjectType);
1545
0
    Entity.setDiag(DD.getDiagnostic());
1546
0
    CheckAccess(*this, Loc, Entity);
1547
0
  } else {
1548
0
    AccessTarget Entity(Context,
1549
0
                        AccessTarget::Base,
1550
0
                        cast<CXXRecordDecl>(TargetD),
1551
0
                        cast<CXXRecordDecl>(NamingD),
1552
0
                        Access);
1553
0
    Entity.setDiag(DD.getDiagnostic());
1554
0
    CheckAccess(*this, Loc, Entity);
1555
0
  }
1556
0
}
1557
1558
Sema::AccessResult Sema::CheckUnresolvedLookupAccess(UnresolvedLookupExpr *E,
1559
0
                                                     DeclAccessPair Found) {
1560
0
  if (!getLangOpts().AccessControl ||
1561
0
      !E->getNamingClass() ||
1562
0
      Found.getAccess() == AS_public)
1563
0
    return AR_accessible;
1564
1565
0
  AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1566
0
                      Found, QualType());
1567
0
  Entity.setDiag(diag::err_access) << E->getSourceRange();
1568
1569
0
  return CheckAccess(*this, E->getNameLoc(), Entity);
1570
0
}
1571
1572
/// Perform access-control checking on a previously-unresolved member
1573
/// access which has now been resolved to a member.
1574
Sema::AccessResult Sema::CheckUnresolvedMemberAccess(UnresolvedMemberExpr *E,
1575
0
                                                     DeclAccessPair Found) {
1576
0
  if (!getLangOpts().AccessControl ||
1577
0
      Found.getAccess() == AS_public)
1578
0
    return AR_accessible;
1579
1580
0
  QualType BaseType = E->getBaseType();
1581
0
  if (E->isArrow())
1582
0
    BaseType = BaseType->castAs<PointerType>()->getPointeeType();
1583
1584
0
  AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1585
0
                      Found, BaseType);
1586
0
  Entity.setDiag(diag::err_access) << E->getSourceRange();
1587
1588
0
  return CheckAccess(*this, E->getMemberLoc(), Entity);
1589
0
}
1590
1591
/// Is the given member accessible for the purposes of deciding whether to
1592
/// define a special member function as deleted?
1593
bool Sema::isMemberAccessibleForDeletion(CXXRecordDecl *NamingClass,
1594
                                         DeclAccessPair Found,
1595
                                         QualType ObjectType,
1596
                                         SourceLocation Loc,
1597
0
                                         const PartialDiagnostic &Diag) {
1598
  // Fast path.
1599
0
  if (Found.getAccess() == AS_public || !getLangOpts().AccessControl)
1600
0
    return true;
1601
1602
0
  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1603
0
                      ObjectType);
1604
1605
  // Suppress diagnostics.
1606
0
  Entity.setDiag(Diag);
1607
1608
0
  switch (CheckAccess(*this, Loc, Entity)) {
1609
0
  case AR_accessible: return true;
1610
0
  case AR_inaccessible: return false;
1611
0
  case AR_dependent: llvm_unreachable("dependent for =delete computation");
1612
0
  case AR_delayed: llvm_unreachable("cannot delay =delete computation");
1613
0
  }
1614
0
  llvm_unreachable("bad access result");
1615
0
}
1616
1617
Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc,
1618
                                               CXXDestructorDecl *Dtor,
1619
                                               const PartialDiagnostic &PDiag,
1620
0
                                               QualType ObjectTy) {
1621
0
  if (!getLangOpts().AccessControl)
1622
0
    return AR_accessible;
1623
1624
  // There's never a path involved when checking implicit destructor access.
1625
0
  AccessSpecifier Access = Dtor->getAccess();
1626
0
  if (Access == AS_public)
1627
0
    return AR_accessible;
1628
1629
0
  CXXRecordDecl *NamingClass = Dtor->getParent();
1630
0
  if (ObjectTy.isNull()) ObjectTy = Context.getTypeDeclType(NamingClass);
1631
1632
0
  AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1633
0
                      DeclAccessPair::make(Dtor, Access),
1634
0
                      ObjectTy);
1635
0
  Entity.setDiag(PDiag); // TODO: avoid copy
1636
1637
0
  return CheckAccess(*this, Loc, Entity);
1638
0
}
1639
1640
/// Checks access to a constructor.
1641
Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
1642
                                                CXXConstructorDecl *Constructor,
1643
                                                DeclAccessPair Found,
1644
                                                const InitializedEntity &Entity,
1645
0
                                                bool IsCopyBindingRefToTemp) {
1646
0
  if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
1647
0
    return AR_accessible;
1648
1649
0
  PartialDiagnostic PD(PDiag());
1650
0
  switch (Entity.getKind()) {
1651
0
  default:
1652
0
    PD = PDiag(IsCopyBindingRefToTemp
1653
0
                 ? diag::ext_rvalue_to_reference_access_ctor
1654
0
                 : diag::err_access_ctor);
1655
1656
0
    break;
1657
1658
0
  case InitializedEntity::EK_Base:
1659
0
    PD = PDiag(diag::err_access_base_ctor);
1660
0
    PD << Entity.isInheritedVirtualBase()
1661
0
       << Entity.getBaseSpecifier()->getType() << getSpecialMember(Constructor);
1662
0
    break;
1663
1664
0
  case InitializedEntity::EK_Member:
1665
0
  case InitializedEntity::EK_ParenAggInitMember: {
1666
0
    const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
1667
0
    PD = PDiag(diag::err_access_field_ctor);
1668
0
    PD << Field->getType() << getSpecialMember(Constructor);
1669
0
    break;
1670
0
  }
1671
1672
0
  case InitializedEntity::EK_LambdaCapture: {
1673
0
    StringRef VarName = Entity.getCapturedVarName();
1674
0
    PD = PDiag(diag::err_access_lambda_capture);
1675
0
    PD << VarName << Entity.getType() << getSpecialMember(Constructor);
1676
0
    break;
1677
0
  }
1678
1679
0
  }
1680
1681
0
  return CheckConstructorAccess(UseLoc, Constructor, Found, Entity, PD);
1682
0
}
1683
1684
/// Checks access to a constructor.
1685
Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
1686
                                                CXXConstructorDecl *Constructor,
1687
                                                DeclAccessPair Found,
1688
                                                const InitializedEntity &Entity,
1689
0
                                                const PartialDiagnostic &PD) {
1690
0
  if (!getLangOpts().AccessControl ||
1691
0
      Found.getAccess() == AS_public)
1692
0
    return AR_accessible;
1693
1694
0
  CXXRecordDecl *NamingClass = Constructor->getParent();
1695
1696
  // Initializing a base sub-object is an instance method call on an
1697
  // object of the derived class.  Otherwise, we have an instance method
1698
  // call on an object of the constructed type.
1699
  //
1700
  // FIXME: If we have a parent, we're initializing the base class subobject
1701
  // in aggregate initialization. It's not clear whether the object class
1702
  // should be the base class or the derived class in that case.
1703
0
  CXXRecordDecl *ObjectClass;
1704
0
  if ((Entity.getKind() == InitializedEntity::EK_Base ||
1705
0
       Entity.getKind() == InitializedEntity::EK_Delegating) &&
1706
0
      !Entity.getParent()) {
1707
0
    ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
1708
0
  } else if (auto *Shadow =
1709
0
                 dyn_cast<ConstructorUsingShadowDecl>(Found.getDecl())) {
1710
    // If we're using an inheriting constructor to construct an object,
1711
    // the object class is the derived class, not the base class.
1712
0
    ObjectClass = Shadow->getParent();
1713
0
  } else {
1714
0
    ObjectClass = NamingClass;
1715
0
  }
1716
1717
0
  AccessTarget AccessEntity(
1718
0
      Context, AccessTarget::Member, NamingClass,
1719
0
      DeclAccessPair::make(Constructor, Found.getAccess()),
1720
0
      Context.getTypeDeclType(ObjectClass));
1721
0
  AccessEntity.setDiag(PD);
1722
1723
0
  return CheckAccess(*this, UseLoc, AccessEntity);
1724
0
}
1725
1726
/// Checks access to an overloaded operator new or delete.
1727
Sema::AccessResult Sema::CheckAllocationAccess(SourceLocation OpLoc,
1728
                                               SourceRange PlacementRange,
1729
                                               CXXRecordDecl *NamingClass,
1730
                                               DeclAccessPair Found,
1731
0
                                               bool Diagnose) {
1732
0
  if (!getLangOpts().AccessControl ||
1733
0
      !NamingClass ||
1734
0
      Found.getAccess() == AS_public)
1735
0
    return AR_accessible;
1736
1737
0
  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1738
0
                      QualType());
1739
0
  if (Diagnose)
1740
0
    Entity.setDiag(diag::err_access)
1741
0
      << PlacementRange;
1742
1743
0
  return CheckAccess(*this, OpLoc, Entity);
1744
0
}
1745
1746
/// Checks access to a member.
1747
Sema::AccessResult Sema::CheckMemberAccess(SourceLocation UseLoc,
1748
                                           CXXRecordDecl *NamingClass,
1749
62
                                           DeclAccessPair Found) {
1750
62
  if (!getLangOpts().AccessControl ||
1751
62
      !NamingClass ||
1752
62
      Found.getAccess() == AS_public)
1753
62
    return AR_accessible;
1754
1755
0
  AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1756
0
                      Found, QualType());
1757
1758
0
  return CheckAccess(*this, UseLoc, Entity);
1759
62
}
1760
1761
/// Checks implicit access to a member in a structured binding.
1762
Sema::AccessResult
1763
Sema::CheckStructuredBindingMemberAccess(SourceLocation UseLoc,
1764
                                         CXXRecordDecl *DecomposedClass,
1765
0
                                         DeclAccessPair Field) {
1766
0
  if (!getLangOpts().AccessControl ||
1767
0
      Field.getAccess() == AS_public)
1768
0
    return AR_accessible;
1769
1770
0
  AccessTarget Entity(Context, AccessTarget::Member, DecomposedClass, Field,
1771
0
                      Context.getRecordType(DecomposedClass));
1772
0
  Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
1773
1774
0
  return CheckAccess(*this, UseLoc, Entity);
1775
0
}
1776
1777
Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
1778
                                                   Expr *ObjectExpr,
1779
                                                   const SourceRange &Range,
1780
0
                                                   DeclAccessPair Found) {
1781
0
  if (!getLangOpts().AccessControl || Found.getAccess() == AS_public)
1782
0
    return AR_accessible;
1783
1784
0
  const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>();
1785
0
  CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
1786
1787
0
  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1788
0
                      ObjectExpr->getType());
1789
0
  Entity.setDiag(diag::err_access) << ObjectExpr->getSourceRange() << Range;
1790
1791
0
  return CheckAccess(*this, OpLoc, Entity);
1792
0
}
1793
1794
/// Checks access to an overloaded member operator, including
1795
/// conversion operators.
1796
Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
1797
                                                   Expr *ObjectExpr,
1798
                                                   Expr *ArgExpr,
1799
0
                                                   DeclAccessPair Found) {
1800
0
  return CheckMemberOperatorAccess(
1801
0
      OpLoc, ObjectExpr, ArgExpr ? ArgExpr->getSourceRange() : SourceRange(),
1802
0
      Found);
1803
0
}
1804
1805
Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
1806
                                                   Expr *ObjectExpr,
1807
                                                   ArrayRef<Expr *> ArgExprs,
1808
0
                                                   DeclAccessPair FoundDecl) {
1809
0
  SourceRange R;
1810
0
  if (!ArgExprs.empty()) {
1811
0
    R = SourceRange(ArgExprs.front()->getBeginLoc(),
1812
0
                    ArgExprs.back()->getEndLoc());
1813
0
  }
1814
1815
0
  return CheckMemberOperatorAccess(OpLoc, ObjectExpr, R, FoundDecl);
1816
0
}
1817
1818
/// Checks access to the target of a friend declaration.
1819
0
Sema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) {
1820
0
  assert(isa<CXXMethodDecl>(target->getAsFunction()));
1821
1822
  // Friendship lookup is a redeclaration lookup, so there's never an
1823
  // inheritance path modifying access.
1824
0
  AccessSpecifier access = target->getAccess();
1825
1826
0
  if (!getLangOpts().AccessControl || access == AS_public)
1827
0
    return AR_accessible;
1828
1829
0
  CXXMethodDecl *method = cast<CXXMethodDecl>(target->getAsFunction());
1830
1831
0
  AccessTarget entity(Context, AccessTarget::Member,
1832
0
                      cast<CXXRecordDecl>(target->getDeclContext()),
1833
0
                      DeclAccessPair::make(target, access),
1834
0
                      /*no instance context*/ QualType());
1835
0
  entity.setDiag(diag::err_access_friend_function)
1836
0
      << (method->getQualifier() ? method->getQualifierLoc().getSourceRange()
1837
0
                                 : method->getNameInfo().getSourceRange());
1838
1839
  // We need to bypass delayed-diagnostics because we might be called
1840
  // while the ParsingDeclarator is active.
1841
0
  EffectiveContext EC(CurContext);
1842
0
  switch (CheckEffectiveAccess(*this, EC, target->getLocation(), entity)) {
1843
0
  case ::AR_accessible: return Sema::AR_accessible;
1844
0
  case ::AR_inaccessible: return Sema::AR_inaccessible;
1845
0
  case ::AR_dependent: return Sema::AR_dependent;
1846
0
  }
1847
0
  llvm_unreachable("invalid access result");
1848
0
}
1849
1850
Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
1851
0
                                                    DeclAccessPair Found) {
1852
0
  if (!getLangOpts().AccessControl ||
1853
0
      Found.getAccess() == AS_none ||
1854
0
      Found.getAccess() == AS_public)
1855
0
    return AR_accessible;
1856
1857
0
  OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).Expression;
1858
0
  CXXRecordDecl *NamingClass = Ovl->getNamingClass();
1859
1860
0
  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1861
0
                      /*no instance context*/ QualType());
1862
0
  Entity.setDiag(diag::err_access)
1863
0
    << Ovl->getSourceRange();
1864
1865
0
  return CheckAccess(*this, Ovl->getNameLoc(), Entity);
1866
0
}
1867
1868
/// Checks access for a hierarchy conversion.
1869
///
1870
/// \param ForceCheck true if this check should be performed even if access
1871
///     control is disabled;  some things rely on this for semantics
1872
/// \param ForceUnprivileged true if this check should proceed as if the
1873
///     context had no special privileges
1874
Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc,
1875
                                              QualType Base,
1876
                                              QualType Derived,
1877
                                              const CXXBasePath &Path,
1878
                                              unsigned DiagID,
1879
                                              bool ForceCheck,
1880
0
                                              bool ForceUnprivileged) {
1881
0
  if (!ForceCheck && !getLangOpts().AccessControl)
1882
0
    return AR_accessible;
1883
1884
0
  if (Path.Access == AS_public)
1885
0
    return AR_accessible;
1886
1887
0
  CXXRecordDecl *BaseD, *DerivedD;
1888
0
  BaseD = cast<CXXRecordDecl>(Base->castAs<RecordType>()->getDecl());
1889
0
  DerivedD = cast<CXXRecordDecl>(Derived->castAs<RecordType>()->getDecl());
1890
1891
0
  AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD,
1892
0
                      Path.Access);
1893
0
  if (DiagID)
1894
0
    Entity.setDiag(DiagID) << Derived << Base;
1895
1896
0
  if (ForceUnprivileged) {
1897
0
    switch (CheckEffectiveAccess(*this, EffectiveContext(),
1898
0
                                 AccessLoc, Entity)) {
1899
0
    case ::AR_accessible: return Sema::AR_accessible;
1900
0
    case ::AR_inaccessible: return Sema::AR_inaccessible;
1901
0
    case ::AR_dependent: return Sema::AR_dependent;
1902
0
    }
1903
0
    llvm_unreachable("unexpected result from CheckEffectiveAccess");
1904
0
  }
1905
0
  return CheckAccess(*this, AccessLoc, Entity);
1906
0
}
1907
1908
/// Checks access to all the declarations in the given result set.
1909
0
void Sema::CheckLookupAccess(const LookupResult &R) {
1910
0
  assert(getLangOpts().AccessControl
1911
0
         && "performing access check without access control");
1912
0
  assert(R.getNamingClass() && "performing access check without naming class");
1913
1914
0
  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
1915
0
    if (I.getAccess() != AS_public) {
1916
0
      AccessTarget Entity(Context, AccessedEntity::Member,
1917
0
                          R.getNamingClass(), I.getPair(),
1918
0
                          R.getBaseObjectType());
1919
0
      Entity.setDiag(diag::err_access);
1920
0
      CheckAccess(*this, R.getNameLoc(), Entity);
1921
0
    }
1922
0
  }
1923
0
}
1924
1925
/// Checks access to Target from the given class. The check will take access
1926
/// specifiers into account, but no member access expressions and such.
1927
///
1928
/// \param Target the declaration to check if it can be accessed
1929
/// \param NamingClass the class in which the lookup was started.
1930
/// \param BaseType type of the left side of member access expression.
1931
///        \p BaseType and \p NamingClass are used for C++ access control.
1932
///        Depending on the lookup case, they should be set to the following:
1933
///        - lhs.target (member access without a qualifier):
1934
///          \p BaseType and \p NamingClass are both the type of 'lhs'.
1935
///        - lhs.X::target (member access with a qualifier):
1936
///          BaseType is the type of 'lhs', NamingClass is 'X'
1937
///        - X::target (qualified lookup without member access):
1938
///          BaseType is null, NamingClass is 'X'.
1939
///        - target (unqualified lookup).
1940
///          BaseType is null, NamingClass is the parent class of 'target'.
1941
/// \return true if the Target is accessible from the Class, false otherwise.
1942
bool Sema::IsSimplyAccessible(NamedDecl *Target, CXXRecordDecl *NamingClass,
1943
0
                              QualType BaseType) {
1944
  // Perform the C++ accessibility checks first.
1945
0
  if (Target->isCXXClassMember() && NamingClass) {
1946
0
    if (!getLangOpts().CPlusPlus)
1947
0
      return false;
1948
    // The unprivileged access is AS_none as we don't know how the member was
1949
    // accessed, which is described by the access in DeclAccessPair.
1950
    // `IsAccessible` will examine the actual access of Target (i.e.
1951
    // Decl->getAccess()) when calculating the access.
1952
0
    AccessTarget Entity(Context, AccessedEntity::Member, NamingClass,
1953
0
                        DeclAccessPair::make(Target, AS_none), BaseType);
1954
0
    EffectiveContext EC(CurContext);
1955
0
    return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible;
1956
0
  }
1957
1958
0
  if (ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Target)) {
1959
    // @public and @package ivars are always accessible.
1960
0
    if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Public ||
1961
0
        Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Package)
1962
0
      return true;
1963
1964
    // If we are inside a class or category implementation, determine the
1965
    // interface we're in.
1966
0
    ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
1967
0
    if (ObjCMethodDecl *MD = getCurMethodDecl())
1968
0
      ClassOfMethodDecl =  MD->getClassInterface();
1969
0
    else if (FunctionDecl *FD = getCurFunctionDecl()) {
1970
0
      if (ObjCImplDecl *Impl
1971
0
            = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1972
0
        if (ObjCImplementationDecl *IMPD
1973
0
              = dyn_cast<ObjCImplementationDecl>(Impl))
1974
0
          ClassOfMethodDecl = IMPD->getClassInterface();
1975
0
        else if (ObjCCategoryImplDecl* CatImplClass
1976
0
                   = dyn_cast<ObjCCategoryImplDecl>(Impl))
1977
0
          ClassOfMethodDecl = CatImplClass->getClassInterface();
1978
0
      }
1979
0
    }
1980
1981
    // If we're not in an interface, this ivar is inaccessible.
1982
0
    if (!ClassOfMethodDecl)
1983
0
      return false;
1984
1985
    // If we're inside the same interface that owns the ivar, we're fine.
1986
0
    if (declaresSameEntity(ClassOfMethodDecl, Ivar->getContainingInterface()))
1987
0
      return true;
1988
1989
    // If the ivar is private, it's inaccessible.
1990
0
    if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Private)
1991
0
      return false;
1992
1993
0
    return Ivar->getContainingInterface()->isSuperClassOf(ClassOfMethodDecl);
1994
0
  }
1995
1996
0
  return true;
1997
0
}