Coverage Report

Created: 2022-07-16 07:03

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