Coverage Report

Created: 2021-09-21 08:58

/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
63.9k
                                    AccessSpecifier LexicalAS) {
42
63.9k
  if (!PrevMemberDecl) {
43
    // Use the lexical access specifier.
44
62.7k
    MemberDecl->setAccess(LexicalAS);
45
62.7k
    return false;
46
62.7k
  }
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.11k
  if (LexicalAS != AS_none && 
LexicalAS != PrevMemberDecl->getAccess()107
) {
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.11k
  MemberDecl->setAccess(PrevMemberDecl->getAccess());
62
1.11k
  return false;
63
1.11k
}
64
65
1.18M
static CXXRecordDecl *FindDeclaringClass(NamedDecl *D) {
66
1.18M
  DeclContext *DC = D->getDeclContext();
67
68
  // This can only happen at top: enum decls only "publish" their
69
  // immediate members.
70
1.18M
  if (isa<EnumDecl>(DC))
71
11.7k
    DC = cast<EnumDecl>(DC)->getDeclContext();
72
73
1.18M
  CXXRecordDecl *DeclaringClass = cast<CXXRecordDecl>(DC);
74
1.18M
  while (DeclaringClass->isAnonymousStructOrUnion())
75
0
    DeclaringClass = cast<CXXRecordDecl>(DeclaringClass->getDeclContext());
76
1.18M
  return DeclaringClass;
77
1.18M
}
78
79
namespace {
80
struct EffectiveContext {
81
15
  EffectiveContext() : Inner(nullptr), Dependent(false) {}
82
83
  explicit EffectiveContext(DeclContext *DC)
84
    : Inner(DC),
85
936k
      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
936k
    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
2.68M
    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
2.68M
      if (isa<CXXRecordDecl>(DC)) {
121
954k
        CXXRecordDecl *Record = cast<CXXRecordDecl>(DC);
122
954k
        Records.push_back(Record->getCanonicalDecl());
123
954k
        DC = Record->getDeclContext();
124
1.72M
      } else if (isa<FunctionDecl>(DC)) {
125
780k
        FunctionDecl *Function = cast<FunctionDecl>(DC);
126
780k
        Functions.push_back(Function->getCanonicalDecl());
127
780k
        if (Function->getFriendObjectKind())
128
6.12k
          DC = Function->getLexicalDeclContext();
129
774k
        else
130
774k
          DC = Function->getDeclContext();
131
947k
      } else if (DC->isFileContext()) {
132
936k
        break;
133
936k
      } else {
134
11.0k
        DC = DC->getParent();
135
11.0k
      }
136
2.68M
    }
137
936k
  }
138
139
117k
  bool isDependent() const { return Dependent; }
140
141
9.16k
  bool includesClass(const CXXRecordDecl *R) const {
142
9.16k
    R = R->getCanonicalDecl();
143
9.16k
    return llvm::find(Records, R) != Records.end();
144
9.16k
  }
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
237k
    : AccessedEntity(Entity) {
165
237k
    initialize();
166
237k
  }
167
168
  AccessTarget(ASTContext &Context,
169
               MemberNonce _,
170
               CXXRecordDecl *NamingClass,
171
               DeclAccessPair FoundDecl,
172
               QualType BaseObjectType)
173
    : AccessedEntity(Context.getDiagAllocator(), Member, NamingClass,
174
942k
                     FoundDecl, BaseObjectType) {
175
942k
    initialize();
176
942k
  }
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
161k
  bool isInstanceMember() const {
189
161k
    return (isMemberAccess() && 
getTargetDecl()->isCXXInstanceMember()161k
);
190
161k
  }
191
192
159k
  bool hasInstanceContext() const {
193
159k
    return HasInstanceContext;
194
159k
  }
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
86.4k
    ~SavedInstanceContext() {
203
86.4k
      if (Target)
204
86.4k
        Target->HasInstanceContext = Has;
205
86.4k
    }
206
207
  private:
208
    friend struct AccessTarget;
209
    explicit SavedInstanceContext(AccessTarget &Target)
210
86.4k
        : Target(&Target), Has(Target.HasInstanceContext) {}
211
    AccessTarget *Target;
212
    bool Has;
213
  };
214
215
86.4k
  SavedInstanceContext saveInstanceContext() {
216
86.4k
    return SavedInstanceContext(*this);
217
86.4k
  }
218
219
72.2k
  void suppressInstanceContext() {
220
72.2k
    HasInstanceContext = false;
221
72.2k
  }
222
223
56.1k
  const CXXRecordDecl *resolveInstanceContext(Sema &S) const {
224
56.1k
    assert(HasInstanceContext);
225
56.1k
    if (CalculatedInstanceContext)
226
565
      return InstanceContext;
227
228
55.5k
    CalculatedInstanceContext = true;
229
55.5k
    DeclContext *IC = S.computeDeclContext(getBaseObjectType());
230
55.5k
    InstanceContext = (IC ? cast<CXXRecordDecl>(IC)->getCanonicalDecl()
231
55.5k
                          : 
nullptr0
);
232
55.5k
    return InstanceContext;
233
56.1k
  }
234
235
91.9k
  const CXXRecordDecl *getDeclaringClass() const {
236
91.9k
    return DeclaringClass;
237
91.9k
  }
238
239
  /// The "effective" naming class is the canonical non-anonymous
240
  /// class containing the actual naming class.
241
936k
  const CXXRecordDecl *getEffectiveNamingClass() const {
242
936k
    const CXXRecordDecl *namingClass = getNamingClass();
243
936k
    while (namingClass->isAnonymousStructOrUnion())
244
0
      namingClass = cast<CXXRecordDecl>(namingClass->getParent());
245
936k
    return namingClass->getCanonicalDecl();
246
936k
  }
247
248
private:
249
1.19M
  void initialize() {
250
1.19M
    HasInstanceContext = (isMemberAccess() &&
251
1.19M
                          
!getBaseObjectType().isNull()1.17M
&&
252
1.19M
                          
getTargetDecl()->isCXXInstanceMember()558k
);
253
1.19M
    CalculatedInstanceContext = false;
254
1.19M
    InstanceContext = nullptr;
255
256
1.19M
    if (isMemberAccess())
257
1.17M
      DeclaringClass = FindDeclaringClass(getTargetDecl());
258
12.3k
    else
259
12.3k
      DeclaringClass = getBaseClass();
260
1.19M
    DeclaringClass = DeclaringClass->getCanonicalDecl();
261
1.19M
  }
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.7k
    return false;
277
278
94
  const DeclContext *FromDC = From->getDeclContext()->getPrimaryContext();
279
94
  const DeclContext *ToDC = To->getDeclContext()->getPrimaryContext();
280
94
  if (FromDC == ToDC) 
return true86
;
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
216k
                                           const CXXRecordDecl *Target) {
294
216k
  assert(Derived->getCanonicalDecl() == Derived);
295
0
  assert(Target->getCanonicalDecl() == Target);
296
297
216k
  if (Derived == Target) 
return AR_accessible169k
;
298
299
46.9k
  bool CheckDependent = Derived->isDependentContext();
300
46.9k
  if (CheckDependent && 
MightInstantiateTo(Derived, Target)2.60k
)
301
24
    return AR_dependent;
302
303
46.9k
  AccessResult OnFailure = AR_inaccessible;
304
46.9k
  SmallVector<const CXXRecordDecl*, 8> Queue; // actually a stack
305
306
47.5k
  while (true) {
307
47.5k
    if (Derived->isDependentContext() && 
!Derived->hasDefinition()2.58k
&&
308
47.5k
        
!Derived->isLambda()1
)
309
1
      return AR_dependent;
310
311
47.5k
    for (const auto &I : Derived->bases()) {
312
45.9k
      const CXXRecordDecl *RD;
313
314
45.9k
      QualType T = I.getType();
315
45.9k
      if (const RecordType *RT = T->getAs<RecordType>()) {
316
45.9k
        RD = cast<CXXRecordDecl>(RT->getDecl());
317
45.9k
      } 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
45.9k
      RD = RD->getCanonicalDecl();
327
45.9k
      if (RD == Target) 
return AR_accessible44.9k
;
328
1.01k
      if (CheckDependent && 
MightInstantiateTo(RD, Target)171
)
329
0
        OnFailure = AR_dependent;
330
331
1.01k
      Queue.push_back(RD);
332
1.01k
    }
333
334
2.57k
    if (Queue.empty()) 
break1.95k
;
335
336
611
    Derived = Queue.pop_back_val();
337
611
  }
338
339
1.95k
  return OnFailure;
340
46.9k
}
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.01k
                               FunctionDecl *Friend) {
377
2.01k
  if (Context->getDeclName() != Friend->getDeclName())
378
1.96k
    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.66k
                               FunctionTemplateDecl *Friend) {
415
1.66k
  return MightInstantiateTo(S,
416
1.66k
                            Context->getTemplatedDecl(),
417
1.66k
                            Friend->getTemplatedDecl());
418
1.66k
}
419
420
static AccessResult MatchesFriend(Sema &S,
421
                                  const EffectiveContext &EC,
422
9.16k
                                  const CXXRecordDecl *Friend) {
423
9.16k
  if (EC.includesClass(Friend))
424
3.36k
    return AR_accessible;
425
426
5.80k
  if (EC.isDependent()) {
427
396
    for (const CXXRecordDecl *Context : EC.Records) {
428
29
      if (MightInstantiateTo(Context, Friend))
429
10
        return AR_dependent;
430
29
    }
431
396
  }
432
433
5.79k
  return AR_inaccessible;
434
5.80k
}
435
436
static AccessResult MatchesFriend(Sema &S,
437
                                  const EffectiveContext &EC,
438
9.16k
                                  CanQualType Friend) {
439
9.16k
  if (const RecordType *RT = Friend->getAs<RecordType>())
440
9.16k
    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.07k
                                  ClassTemplateDecl *Friend) {
454
7.07k
  AccessResult OnFailure = AR_inaccessible;
455
456
  // Check whether the friend is the template of a class in the
457
  // context chain.
458
7.07k
  for (SmallVectorImpl<CXXRecordDecl*>::const_iterator
459
13.0k
         I = EC.Records.begin(), E = EC.Records.end(); I != E; 
++I5.98k
) {
460
7.68k
    CXXRecordDecl *Record = *I;
461
462
    // Figure out whether the current class has a template:
463
7.68k
    ClassTemplateDecl *CTD;
464
465
    // A specialization of the template...
466
7.68k
    if (isa<ClassTemplateSpecializationDecl>(Record)) {
467
3.30k
      CTD = cast<ClassTemplateSpecializationDecl>(Record)
468
3.30k
        ->getSpecializedTemplate();
469
470
    // ... or the template pattern itself.
471
4.37k
    } else {
472
4.37k
      CTD = Record->getDescribedClassTemplate();
473
4.37k
      if (!CTD) 
continue651
;
474
4.37k
    }
475
476
    // It's a match.
477
7.03k
    if (Friend == CTD->getCanonicalDecl())
478
1.70k
      return AR_accessible;
479
480
    // If the context isn't dependent, it can't be a dependent match.
481
5.33k
    if (!EC.isDependent())
482
2.33k
      continue;
483
484
    // If the template names don't match, it can't be a dependent
485
    // match.
486
2.99k
    if (CTD->getDeclName() != Friend->getDeclName())
487
2.99k
      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.37k
  return OnFailure;
500
7.07k
}
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.53k
                                  FunctionDecl *Friend) {
507
5.53k
  AccessResult OnFailure = AR_inaccessible;
508
509
5.53k
  for (SmallVectorImpl<FunctionDecl*>::const_iterator
510
9.84k
         I = EC.Functions.begin(), E = EC.Functions.end(); I != E; 
++I4.30k
) {
511
5.51k
    if (Friend == *I)
512
1.20k
      return AR_accessible;
513
514
4.30k
    if (EC.isDependent() && 
MightInstantiateTo(S, *I, Friend)358
)
515
35
      OnFailure = AR_dependent;
516
4.30k
  }
517
518
4.32k
  return OnFailure;
519
5.53k
}
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
26.4k
                                  FunctionTemplateDecl *Friend) {
526
26.4k
  if (EC.Functions.empty()) 
return AR_inaccessible46
;
527
528
26.3k
  AccessResult OnFailure = AR_inaccessible;
529
530
26.3k
  for (SmallVectorImpl<FunctionDecl*>::const_iterator
531
50.3k
         I = EC.Functions.begin(), E = EC.Functions.end(); I != E; 
++I23.9k
) {
532
533
26.3k
    FunctionTemplateDecl *FTD = (*I)->getPrimaryTemplate();
534
26.3k
    if (!FTD)
535
10.8k
      FTD = (*I)->getDescribedFunctionTemplate();
536
26.3k
    if (!FTD)
537
8.50k
      continue;
538
539
17.8k
    FTD = FTD->getCanonicalDecl();
540
541
17.8k
    if (Friend == FTD)
542
2.42k
      return AR_accessible;
543
544
15.4k
    if (EC.isDependent() && 
MightInstantiateTo(S, FTD, Friend)1.66k
)
545
0
      OnFailure = AR_dependent;
546
15.4k
  }
547
548
23.9k
  return OnFailure;
549
26.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
48.2k
                                  FriendDecl *FriendD) {
556
  // Whitelist accesses if there's an invalid or unsupported friend
557
  // declaration.
558
48.2k
  if (FriendD->isInvalidDecl() || FriendD->isUnsupportedFriend())
559
38
    return AR_accessible;
560
561
48.2k
  if (TypeSourceInfo *T = FriendD->getFriendType())
562
9.16k
    return MatchesFriend(S, EC, T->getType()->getCanonicalTypeUnqualified());
563
564
39.0k
  NamedDecl *Friend
565
39.0k
    = cast<NamedDecl>(FriendD->getFriendDecl()->getCanonicalDecl());
566
567
  // FIXME: declarations with dependent or templated scope.
568
569
39.0k
  if (isa<ClassTemplateDecl>(Friend))
570
7.07k
    return MatchesFriend(S, EC, cast<ClassTemplateDecl>(Friend));
571
572
31.9k
  if (isa<FunctionTemplateDecl>(Friend))
573
26.4k
    return MatchesFriend(S, EC, cast<FunctionTemplateDecl>(Friend));
574
575
5.53k
  if (isa<CXXRecordDecl>(Friend))
576
0
    return MatchesFriend(S, EC, cast<CXXRecordDecl>(Friend));
577
578
5.53k
  assert(isa<FunctionDecl>(Friend) && "unknown friend decl kind");
579
0
  return MatchesFriend(S, EC, cast<FunctionDecl>(Friend));
580
5.53k
}
581
582
static AccessResult GetFriendKind(Sema &S,
583
                                  const EffectiveContext &EC,
584
96.9k
                                  const CXXRecordDecl *Class) {
585
96.9k
  AccessResult OnFailure = AR_inaccessible;
586
587
  // Okay, check friends.
588
96.9k
  for (auto *Friend : Class->friends()) {
589
48.2k
    switch (MatchesFriend(S, EC, Friend)) {
590
8.74k
    case AR_accessible:
591
8.74k
      return AR_accessible;
592
593
39.4k
    case AR_inaccessible:
594
39.4k
      continue;
595
596
45
    case AR_dependent:
597
45
      OnFailure = AR_dependent;
598
45
      break;
599
48.2k
    }
600
48.2k
  }
601
602
  // That's it, give up.
603
88.1k
  return OnFailure;
604
96.9k
}
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
680
      EverDependent(false) {}
627
628
  /// Check classes in the current path for friendship, starting at
629
  /// the given index.
630
662
  bool checkFriendshipAlongPath(unsigned I) {
631
662
    assert(I < CurPath.size());
632
1.51k
    for (unsigned E = CurPath.size(); I != E; 
++I851
) {
633
943
      switch (GetFriendKind(S, EC, CurPath[I])) {
634
92
      case AR_accessible:   return true;
635
851
      case AR_inaccessible: continue;
636
0
      case AR_dependent:    EverDependent = true; continue;
637
943
      }
638
943
    }
639
570
    return false;
640
662
  }
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
993
  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
993
    if (Cur == NamingClass)
652
662
      return checkFriendshipAlongPath(PrivateDepth);
653
654
331
    if (CheckDependent && 
MightInstantiateTo(Cur, NamingClass)0
)
655
0
      EverDependent = true;
656
657
    // Recurse into the base classes.
658
331
    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
313
      unsigned BasePrivateDepth = PrivateDepth;
662
313
      if (I.getAccessSpecifier() == AS_private)
663
33
        BasePrivateDepth = CurPath.size() - 1;
664
665
313
      const CXXRecordDecl *RD;
666
667
313
      QualType T = I.getType();
668
313
      if (const RecordType *RT = T->getAs<RecordType>()) {
669
313
        RD = cast<CXXRecordDecl>(RT->getDecl());
670
313
      } 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
313
      CurPath.push_back(RD);
681
313
      if (findFriendship(RD->getCanonicalDecl(), BasePrivateDepth))
682
209
        return true;
683
104
      CurPath.pop_back();
684
104
    }
685
686
122
    return false;
687
331
  }
688
689
680
  bool findFriendship(const CXXRecordDecl *Cur) {
690
680
    assert(CurPath.empty());
691
0
    CurPath.push_back(Cur);
692
680
    return findFriendship(Cur, 0);
693
680
  }
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
895
                                           const CXXRecordDecl *NamingClass) {
726
895
  assert(InstanceContext == nullptr ||
727
895
         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
895
  if (!InstanceContext) 
return GetFriendKind(S, EC, NamingClass)215
;
734
735
680
  ProtectedFriendContext PRC(S, EC, InstanceContext, NamingClass);
736
680
  if (PRC.findFriendship(InstanceContext)) 
return AR_accessible92
;
737
588
  if (PRC.EverDependent) 
return AR_dependent0
;
738
588
  return AR_inaccessible;
739
588
}
740
741
static AccessResult HasAccess(Sema &S,
742
                              const EffectiveContext &EC,
743
                              const CXXRecordDecl *NamingClass,
744
                              AccessSpecifier Access,
745
1.01M
                              const AccessTarget &Target) {
746
1.01M
  assert(NamingClass->getCanonicalDecl() == NamingClass &&
747
1.01M
         "declaration should be canonicalized before being passed here");
748
749
1.01M
  if (Access == AS_public) 
return AR_accessible71.0k
;
750
944k
  assert(Access == AS_private || Access == AS_protected);
751
752
0
  AccessResult OnFailure = AR_inaccessible;
753
754
944k
  for (EffectiveContext::record_iterator
755
1.03M
         I = EC.Records.begin(), E = EC.Records.end(); I != E; 
++I88.2k
) {
756
    // All the declarations in EC have been canonicalized, so pointer
757
    // equality from this point on will work fine.
758
936k
    const CXXRecordDecl *ECRecord = *I;
759
760
    // [B2] and [M2]
761
936k
    if (Access == AS_private) {
762
776k
      if (ECRecord == NamingClass)
763
689k
        return AR_accessible;
764
765
86.2k
      if (EC.isDependent() && 
MightInstantiateTo(ECRecord, NamingClass)8.00k
)
766
60
        OnFailure = AR_dependent;
767
768
    // [B3] and [M3]
769
160k
    } else {
770
160k
      assert(Access == AS_protected);
771
0
      switch (IsDerivedFromInclusive(ECRecord, NamingClass)) {
772
158k
      case AR_accessible: break;
773
1.76k
      case AR_inaccessible: continue;
774
37
      case AR_dependent: OnFailure = AR_dependent; continue;
775
160k
      }
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
158k
      if (!Target.hasInstanceContext()) {
795
        // If it's not an instance member, these restrictions don't apply.
796
103k
        if (!Target.isInstanceMember()) 
return AR_accessible103k
;
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
55.4k
      assert(Target.isInstanceMember());
832
833
0
      const CXXRecordDecl *InstanceContext = Target.resolveInstanceContext(S);
834
55.4k
      if (!InstanceContext) {
835
0
        OnFailure = AR_dependent;
836
0
        continue;
837
0
      }
838
839
55.4k
      switch (IsDerivedFromInclusive(InstanceContext, ECRecord)) {
840
55.3k
      case AR_accessible: return AR_accessible;
841
113
      case AR_inaccessible: continue;
842
0
      case AR_dependent: OnFailure = AR_dependent; continue;
843
55.4k
      }
844
55.4k
    }
845
936k
  }
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
96.6k
  if (Access == AS_protected && 
Target.isInstanceMember()2.55k
) {
858
    // Compute the instance context if possible.
859
895
    const CXXRecordDecl *InstanceContext = nullptr;
860
895
    if (Target.hasInstanceContext()) {
861
680
      InstanceContext = Target.resolveInstanceContext(S);
862
680
      if (!InstanceContext) 
return AR_dependent0
;
863
680
    }
864
865
895
    switch (GetProtectedFriendKind(S, EC, InstanceContext, NamingClass)) {
866
95
    case AR_accessible: return AR_accessible;
867
800
    case AR_inaccessible: return OnFailure;
868
0
    case AR_dependent: return AR_dependent;
869
895
    }
870
0
    llvm_unreachable("impossible friendship kind");
871
0
  }
872
873
95.7k
  switch (GetFriendKind(S, EC, NamingClass)) {
874
8.64k
  case AR_accessible: return AR_accessible;
875
87.0k
  case AR_inaccessible: return OnFailure;
876
45
  case AR_dependent: return AR_dependent;
877
95.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.15k
                                 CXXBasePaths &Paths) {
944
  // Derive the paths to the desired base.
945
1.15k
  const CXXRecordDecl *Derived = Target.getNamingClass();
946
1.15k
  const CXXRecordDecl *Base = Target.getDeclaringClass();
947
948
  // FIXME: fail correctly when there are dependent paths.
949
1.15k
  bool isDerived = Derived->isDerivedFrom(const_cast<CXXRecordDecl*>(Base),
950
1.15k
                                          Paths);
951
1.15k
  assert(isDerived && "derived class not actually derived from base");
952
0
  (void) isDerived;
953
954
1.15k
  CXXBasePath *BestPath = nullptr;
955
956
1.15k
  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.15k
  for (CXXBasePaths::paths_iterator PI = Paths.begin(), PE = Paths.end();
962
1.90k
         PI != PE; 
++PI748
) {
963
1.16k
    AccessTarget::SavedInstanceContext _ = Target.saveInstanceContext();
964
965
    // Walk through the path backwards.
966
1.16k
    AccessSpecifier PathAccess = FinalAccess;
967
1.16k
    CXXBasePath::iterator I = PI->end(), E = PI->begin();
968
2.49k
    while (I != E) {
969
1.60k
      --I;
970
971
1.60k
      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.60k
      if (PathAccess == AS_private) {
977
273
        PathAccess = AS_none;
978
273
        break;
979
273
      }
980
981
1.33k
      const CXXRecordDecl *NC = I->Class->getCanonicalDecl();
982
983
1.33k
      AccessSpecifier BaseAccess = I->Base->getAccessSpecifier();
984
1.33k
      PathAccess = std::max(PathAccess, BaseAccess);
985
986
1.33k
      switch (HasAccess(S, EC, NC, PathAccess, Target)) {
987
682
      case AR_inaccessible: break;
988
653
      case AR_accessible:
989
653
        PathAccess = AS_public;
990
991
        // Future tests are not against members and so do not have
992
        // instance context.
993
653
        Target.suppressInstanceContext();
994
653
        break;
995
0
      case AR_dependent:
996
0
        AnyDependent = true;
997
0
        goto Next;
998
1.33k
      }
999
1.33k
    }
1000
1001
    // Note that we modify the path's Access field to the
1002
    // friend-modified access.
1003
1.16k
    if (BestPath == nullptr || 
PathAccess < BestPath->Access2
) {
1004
1.16k
      BestPath = &*PI;
1005
1.16k
      BestPath->Access = PathAccess;
1006
1007
      // Short-circuit if we found a public path.
1008
1.16k
      if (BestPath->Access == AS_public)
1009
412
        return BestPath;
1010
1.16k
    }
1011
1012
748
  Next: ;
1013
748
  }
1014
1015
746
  assert((!BestPath || BestPath->Access != AS_public) &&
1016
746
         "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
746
  if (AnyDependent)
1021
0
    return nullptr;
1022
1023
746
  return BestPath;
1024
746
}
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
258
                                       AccessTarget &Target) {
1033
  // Only applies to instance accesses.
1034
258
  if (!Target.isInstanceMember())
1035
104
    return false;
1036
1037
154
  assert(Target.isMemberAccess());
1038
1039
0
  const CXXRecordDecl *NamingClass = Target.getEffectiveNamingClass();
1040
1041
154
  for (EffectiveContext::record_iterator
1042
196
         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
119
  return false;
1102
154
}
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
4.64k
                                    AccessTarget &entity) {
1109
4.64k
  assert(entity.isMemberAccess());
1110
0
  NamedDecl *D = entity.getTargetDecl();
1111
1112
4.64k
  if (D->getAccess() == AS_protected &&
1113
4.64k
      
TryDiagnoseProtectedAccess(S, EC, entity)258
)
1114
35
    return;
1115
1116
  // Find an original declaration.
1117
4.63k
  
while (4.60k
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
4.60k
  CXXRecordDecl *DeclaringClass = FindDeclaringClass(D);
1135
4.60k
  Decl *ImmediateChild;
1136
4.60k
  if (D->getDeclContext() == DeclaringClass)
1137
4.60k
    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
4.60k
  bool isImplicit = true;
1148
13.4k
  for (const auto *I : DeclaringClass->decls()) {
1149
13.4k
    if (I == ImmediateChild) 
break4.00k
;
1150
9.42k
    if (isa<AccessSpecDecl>(I)) {
1151
601
      isImplicit = false;
1152
601
      break;
1153
601
    }
1154
9.42k
  }
1155
1156
4.60k
  S.Diag(D->getLocation(), diag::note_access_natural)
1157
4.60k
    << (unsigned) (D->getAccess() == AS_protected)
1158
4.60k
    << isImplicit;
1159
4.60k
}
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
4.88k
                               AccessTarget &entity) {
1166
  // Save the instance context to preserve invariants.
1167
4.88k
  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
4.88k
  AccessSpecifier accessSoFar = AS_public;
1174
1175
  // Check whether we have special rights to the declaring class.
1176
4.88k
  if (entity.isMemberAccess()) {
1177
4.77k
    NamedDecl *D = entity.getTargetDecl();
1178
4.77k
    accessSoFar = D->getAccess();
1179
4.77k
    const CXXRecordDecl *declaringClass = entity.getDeclaringClass();
1180
1181
4.77k
    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
130
    case AR_accessible:
1185
130
      accessSoFar = AS_public;
1186
130
      entity.suppressInstanceContext();
1187
130
      break;
1188
1189
4.64k
    case AR_inaccessible:
1190
4.64k
      if (accessSoFar == AS_private ||
1191
4.64k
          
declaringClass == entity.getEffectiveNamingClass()263
)
1192
4.59k
        return diagnoseBadDirectAccess(S, EC, entity);
1193
53
      break;
1194
1195
53
    case AR_dependent:
1196
0
      llvm_unreachable("cannot diagnose dependent access");
1197
4.77k
    }
1198
4.77k
  }
1199
1200
293
  CXXBasePaths paths;
1201
293
  CXXBasePath &path = *FindBestPath(S, EC, entity, accessSoFar, paths);
1202
293
  assert(path.Access != AS_public);
1203
1204
0
  CXXBasePath::iterator i = path.end(), e = path.begin();
1205
293
  CXXBasePath::iterator constrainingBase = i;
1206
399
  while (i != e) {
1207
313
    --i;
1208
1209
313
    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
313
    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
313
    AccessSpecifier baseAccess = base->getAccessSpecifier();
1219
313
    if (baseAccess > accessSoFar) {
1220
245
      constrainingBase = i;
1221
245
      accessSoFar = baseAccess;
1222
245
    }
1223
1224
313
    switch (HasAccess(S, EC, derivingClass, accessSoFar, entity)) {
1225
301
    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
313
    }
1234
1235
    // If this was private inheritance, but we don't have access to
1236
    // the deriving class, we're done.
1237
313
    if (accessSoFar == AS_private) {
1238
207
      assert(baseAccess == AS_private);
1239
0
      assert(constrainingBase == i);
1240
0
      break;
1241
207
    }
1242
313
  }
1243
1244
  // If we don't have a constraining base, the access failure must be
1245
  // due to the original declaration.
1246
293
  if (constrainingBase == path.end())
1247
48
    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
245
  unsigned diagnostic;
1253
245
  if (entity.isMemberAccess() ||
1254
245
      
constrainingBase + 1 != path.end()110
) {
1255
136
    diagnostic = diag::note_access_constrained_by_path;
1256
136
  } else {
1257
109
    diagnostic = diag::note_access_natural;
1258
109
  }
1259
1260
245
  const CXXBaseSpecifier *base = constrainingBase->Base;
1261
1262
245
  S.Diag(base->getSourceRange().getBegin(), diagnostic)
1263
245
    << base->getSourceRange()
1264
245
    << (base->getAccessSpecifier() == AS_protected)
1265
245
    << (base->getAccessSpecifierAsWritten() == AS_none);
1266
1267
245
  if (entity.isMemberAccess())
1268
135
    S.Diag(entity.getTargetDecl()->getLocation(),
1269
135
           diag::note_member_declared_at);
1270
245
}
1271
1272
static void DiagnoseBadAccess(Sema &S, SourceLocation Loc,
1273
                              const EffectiveContext &EC,
1274
4.88k
                              AccessTarget &Entity) {
1275
4.88k
  const CXXRecordDecl *NamingClass = Entity.getNamingClass();
1276
4.88k
  const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1277
4.88k
  NamedDecl *D = (Entity.isMemberAccess() ? 
Entity.getTargetDecl()4.77k
:
nullptr110
);
1278
1279
4.88k
  S.Diag(Loc, Entity.getDiag())
1280
4.88k
    << (Entity.getAccess() == AS_protected)
1281
4.88k
    << (D ? 
D->getDeclName()4.77k
:
DeclarationName()110
)
1282
4.88k
    << S.Context.getTypeDeclType(NamingClass)
1283
4.88k
    << S.Context.getTypeDeclType(DeclaringClass);
1284
4.88k
  DiagnoseAccessPath(S, EC, Entity);
1285
4.88k
}
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
19
                                                 AccessTarget &Entity) {
1310
19
  if (UsingShadowDecl *Shadow =
1311
19
          dyn_cast<UsingShadowDecl>(Entity.getTargetDecl()))
1312
4
    if (UsingDecl *UD = dyn_cast<UsingDecl>(Shadow->getIntroducer())) {
1313
4
      const NamedDecl *OrigDecl = Entity.getTargetDecl()->getUnderlyingDecl();
1314
4
      if (Entity.getTargetDecl()->getAccess() == AS_private &&
1315
4
          (OrigDecl->getAccess() == AS_public ||
1316
4
           
OrigDecl->getAccess() == AS_protected0
)) {
1317
4
        S.Diag(AccessLoc, diag::ext_ms_using_declaration_inaccessible)
1318
4
            << UD->getQualifiedNameAsString()
1319
4
            << OrigDecl->getQualifiedNameAsString();
1320
4
        return true;
1321
4
      }
1322
4
    }
1323
15
  return false;
1324
19
}
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
936k
                                 AccessTarget &Entity) {
1331
  // Determine the actual naming class.
1332
936k
  const CXXRecordDecl *NamingClass = Entity.getEffectiveNamingClass();
1333
1334
936k
  AccessSpecifier UnprivilegedAccess = Entity.getAccess();
1335
936k
  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
936k
  if (UnprivilegedAccess != AS_none) {
1342
929k
    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
855k
    case AR_accessible: return AR_accessible;
1354
73.3k
    case AR_inaccessible: break;
1355
929k
    }
1356
929k
  }
1357
1358
80.4k
  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
80.4k
  AccessSpecifier FinalAccess;
1363
1364
80.4k
  if (Entity.isMemberAccess()) {
1365
    // Determine if the declaration is accessible from EC when named
1366
    // in its declaring class.
1367
80.2k
    NamedDecl *Target = Entity.getTargetDecl();
1368
80.2k
    const CXXRecordDecl *DeclaringClass = Entity.getDeclaringClass();
1369
1370
80.2k
    FinalAccess = Target->getAccess();
1371
80.2k
    switch (HasAccess(S, EC, DeclaringClass, FinalAccess, Entity)) {
1372
71.4k
    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
71.4k
      FinalAccess = AS_public;
1379
71.4k
      Entity.suppressInstanceContext();
1380
71.4k
      break;
1381
8.85k
    case AR_inaccessible: break;
1382
0
    case AR_dependent: return AR_dependent; // see above
1383
80.2k
    }
1384
1385
80.2k
    if (DeclaringClass == NamingClass)
1386
79.5k
      return (FinalAccess == AS_public ? 
AR_accessible70.8k
:
AR_inaccessible8.70k
);
1387
80.2k
  } else {
1388
128
    FinalAccess = AS_public;
1389
128
  }
1390
1391
865
  assert(Entity.getDeclaringClass() != NamingClass);
1392
1393
  // Append the declaration's access if applicable.
1394
0
  CXXBasePaths Paths;
1395
865
  CXXBasePath *Path = FindBestPath(S, EC, Entity, FinalAccess, Paths);
1396
865
  if (!Path)
1397
0
    return AR_dependent;
1398
1399
865
  assert(Path->Access <= UnprivilegedAccess &&
1400
865
         "access along best path worse than direct?");
1401
865
  if (Path->Access == AS_public)
1402
412
    return AR_accessible;
1403
453
  return AR_inaccessible;
1404
865
}
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
934k
                                         AccessTarget &Entity) {
1428
934k
  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.09k
  case AR_inaccessible:
1436
9.09k
    if (S.getLangOpts().MSVCCompat &&
1437
9.09k
        
IsMicrosoftUsingDeclarationAccessBug(S, Loc, Entity)19
)
1438
4
      return AR_accessible;
1439
9.08k
    if (!Entity.isQuiet())
1440
4.88k
      DiagnoseBadAccess(S, Loc, EC, Entity);
1441
9.08k
    return AR_inaccessible;
1442
1443
925k
  case AR_accessible:
1444
925k
    return AR_accessible;
1445
934k
  }
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
952k
                                      AccessTarget &Entity) {
1453
  // If the access path is public, it's accessible everywhere.
1454
952k
  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
952k
  if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
1469
255k
    S.DelayedDiagnostics.add(DelayedDiagnostic::makeAccess(Loc, Entity));
1470
255k
    return Sema::AR_delayed;
1471
255k
  }
1472
1473
696k
  EffectiveContext EC(S.CurContext);
1474
696k
  switch (CheckEffectiveAccess(S, EC, Loc, Entity)) {
1475
688k
  case AR_accessible: return Sema::AR_accessible;
1476
8.62k
  case AR_inaccessible: return Sema::AR_inaccessible;
1477
86
  case AR_dependent: return Sema::AR_dependent;
1478
696k
  }
1479
0
  llvm_unreachable("invalid access result");
1480
0
}
1481
1482
237k
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
237k
  DeclContext *DC = D->getDeclContext();
1489
237k
  if (D->isLocalExternDecl()) {
1490
10
    DC = D->getLexicalDeclContext();
1491
237k
  } else if (FunctionDecl *FN = dyn_cast<FunctionDecl>(D)) {
1492
54.9k
    DC = FN;
1493
182k
  } else if (TemplateDecl *TD = dyn_cast<TemplateDecl>(D)) {
1494
35.1k
    if (isa<DeclContext>(TD->getTemplatedDecl()))
1495
35.1k
      DC = cast<DeclContext>(TD->getTemplatedDecl());
1496
35.1k
  }
1497
1498
237k
  EffectiveContext EC(DC);
1499
1500
237k
  AccessTarget Target(DD.getAccessData());
1501
1502
237k
  if (CheckEffectiveAccess(*this, EC, DD.Loc, Target) == ::AR_inaccessible)
1503
438
    DD.Triggered = true;
1504
237k
}
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
732k
                                                     DeclAccessPair Found) {
1548
732k
  if (!getLangOpts().AccessControl ||
1549
732k
      
!E->getNamingClass()659k
||
1550
732k
      
Found.getAccess() == AS_public42.5k
)
1551
728k
    return AR_accessible;
1552
1553
4.20k
  AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1554
4.20k
                      Found, QualType());
1555
4.20k
  Entity.setDiag(diag::err_access) << E->getSourceRange();
1556
1557
4.20k
  return CheckAccess(*this, E->getNameLoc(), Entity);
1558
732k
}
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
78.5k
                                                     DeclAccessPair Found) {
1564
78.5k
  if (!getLangOpts().AccessControl ||
1565
78.5k
      
Found.getAccess() == AS_public74.4k
)
1566
67.2k
    return AR_accessible;
1567
1568
11.3k
  QualType BaseType = E->getBaseType();
1569
11.3k
  if (E->isArrow())
1570
10.9k
    BaseType = BaseType->castAs<PointerType>()->getPointeeType();
1571
1572
11.3k
  AccessTarget Entity(Context, AccessTarget::Member, E->getNamingClass(),
1573
11.3k
                      Found, BaseType);
1574
11.3k
  Entity.setDiag(diag::err_access) << E->getSourceRange();
1575
1576
11.3k
  return CheckAccess(*this, E->getMemberLoc(), Entity);
1577
78.5k
}
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
270k
                                         const PartialDiagnostic &Diag) {
1586
  // Fast path.
1587
270k
  if (Found.getAccess() == AS_public || 
!getLangOpts().AccessControl80.0k
)
1588
196k
    return true;
1589
1590
74.7k
  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1591
74.7k
                      ObjectType);
1592
1593
  // Suppress diagnostics.
1594
74.7k
  Entity.setDiag(Diag);
1595
1596
74.7k
  switch (CheckAccess(*this, Loc, Entity)) {
1597
70.6k
  case AR_accessible: return true;
1598
4.02k
  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
74.7k
  }
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
278k
                                               QualType ObjectTy) {
1609
278k
  if (!getLangOpts().AccessControl)
1610
2.52k
    return AR_accessible;
1611
1612
  // There's never a path involved when checking implicit destructor access.
1613
275k
  AccessSpecifier Access = Dtor->getAccess();
1614
275k
  if (Access == AS_public)
1615
272k
    return AR_accessible;
1616
1617
2.65k
  CXXRecordDecl *NamingClass = Dtor->getParent();
1618
2.65k
  if (ObjectTy.isNull()) 
ObjectTy = Context.getTypeDeclType(NamingClass)167
;
1619
1620
2.65k
  AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
1621
2.65k
                      DeclAccessPair::make(Dtor, Access),
1622
2.65k
                      ObjectTy);
1623
2.65k
  Entity.setDiag(PDiag); // TODO: avoid copy
1624
1625
2.65k
  return CheckAccess(*this, Loc, Entity);
1626
275k
}
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
343k
                                                bool IsCopyBindingRefToTemp) {
1634
343k
  if (!getLangOpts().AccessControl || 
Found.getAccess() == AS_public340k
)
1635
336k
    return AR_accessible;
1636
1637
7.00k
  PartialDiagnostic PD(PDiag());
1638
7.00k
  switch (Entity.getKind()) {
1639
4.09k
  default:
1640
4.09k
    PD = PDiag(IsCopyBindingRefToTemp
1641
4.09k
                 ? 
diag::ext_rvalue_to_reference_access_ctor7
1642
4.09k
                 : 
diag::err_access_ctor4.09k
);
1643
1644
4.09k
    break;
1645
1646
2.88k
  case InitializedEntity::EK_Base:
1647
2.88k
    PD = PDiag(diag::err_access_base_ctor);
1648
2.88k
    PD << Entity.isInheritedVirtualBase()
1649
2.88k
       << Entity.getBaseSpecifier()->getType() << getSpecialMember(Constructor);
1650
2.88k
    break;
1651
1652
24
  case InitializedEntity::EK_Member: {
1653
24
    const FieldDecl *Field = cast<FieldDecl>(Entity.getDecl());
1654
24
    PD = PDiag(diag::err_access_field_ctor);
1655
24
    PD << Field->getType() << getSpecialMember(Constructor);
1656
24
    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.00k
  }
1667
1668
7.00k
  return CheckConstructorAccess(UseLoc, Constructor, Found, Entity, PD);
1669
7.00k
}
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.03k
                                                const PartialDiagnostic &PD) {
1677
7.03k
  if (!getLangOpts().AccessControl ||
1678
7.03k
      Found.getAccess() == AS_public)
1679
21
    return AR_accessible;
1680
1681
7.01k
  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.01k
  CXXRecordDecl *ObjectClass;
1691
7.01k
  if ((Entity.getKind() == InitializedEntity::EK_Base ||
1692
7.01k
       
Entity.getKind() == InitializedEntity::EK_Delegating4.13k
) &&
1693
7.01k
      
!Entity.getParent()3.10k
) {
1694
3.09k
    ObjectClass = cast<CXXConstructorDecl>(CurContext)->getParent();
1695
3.91k
  } else if (auto *Shadow =
1696
3.91k
                 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
3.89k
  } else {
1701
3.89k
    ObjectClass = NamingClass;
1702
3.89k
  }
1703
1704
7.01k
  AccessTarget AccessEntity(
1705
7.01k
      Context, AccessTarget::Member, NamingClass,
1706
7.01k
      DeclAccessPair::make(Constructor, Found.getAccess()),
1707
7.01k
      Context.getTypeDeclType(ObjectClass));
1708
7.01k
  AccessEntity.setDiag(PD);
1709
1710
7.01k
  return CheckAccess(*this, UseLoc, AccessEntity);
1711
7.03k
}
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
8.77k
                                               bool Diagnose) {
1719
8.77k
  if (!getLangOpts().AccessControl ||
1720
8.77k
      
!NamingClass8.68k
||
1721
8.77k
      
Found.getAccess() == AS_public649
)
1722
8.74k
    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
8.77k
}
1732
1733
/// Checks access to a member.
1734
Sema::AccessResult Sema::CheckMemberAccess(SourceLocation UseLoc,
1735
                                           CXXRecordDecl *NamingClass,
1736
2.17k
                                           DeclAccessPair Found) {
1737
2.17k
  if (!getLangOpts().AccessControl ||
1738
2.17k
      !NamingClass ||
1739
2.17k
      
Found.getAccess() == AS_public982
)
1740
2.00k
    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.17k
}
1747
1748
/// Checks implicit access to a member in a structured binding.
1749
Sema::AccessResult
1750
Sema::CheckStructuredBindingMemberAccess(SourceLocation UseLoc,
1751
                                         CXXRecordDecl *DecomposedClass,
1752
346
                                         DeclAccessPair Field) {
1753
346
  if (!getLangOpts().AccessControl ||
1754
346
      Field.getAccess() == AS_public)
1755
331
    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
346
}
1763
1764
/// Checks access to an overloaded member operator, including
1765
/// conversion operators.
1766
Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
1767
                                                   Expr *ObjectExpr,
1768
                                                   Expr *ArgExpr,
1769
90.0k
                                                   DeclAccessPair Found) {
1770
90.0k
  if (!getLangOpts().AccessControl ||
1771
90.0k
      
Found.getAccess() == AS_public88.4k
)
1772
88.3k
    return AR_accessible;
1773
1774
1.65k
  const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>();
1775
1.65k
  CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
1776
1777
1.65k
  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1778
1.65k
                      ObjectExpr->getType());
1779
1.65k
  Entity.setDiag(diag::err_access)
1780
1.65k
    << ObjectExpr->getSourceRange()
1781
1.65k
    << (ArgExpr ? 
ArgExpr->getSourceRange()1.55k
:
SourceRange()95
);
1782
1783
1.65k
  return CheckAccess(*this, OpLoc, Entity);
1784
90.0k
}
1785
1786
/// Checks access to the target of a friend declaration.
1787
403
Sema::AccessResult Sema::CheckFriendAccess(NamedDecl *target) {
1788
403
  assert(isa<CXXMethodDecl>(target->getAsFunction()));
1789
1790
  // Friendship lookup is a redeclaration lookup, so there's never an
1791
  // inheritance path modifying access.
1792
0
  AccessSpecifier access = target->getAccess();
1793
1794
403
  if (!getLangOpts().AccessControl || access == AS_public)
1795
380
    return AR_accessible;
1796
1797
23
  CXXMethodDecl *method = cast<CXXMethodDecl>(target->getAsFunction());
1798
1799
23
  AccessTarget entity(Context, AccessTarget::Member,
1800
23
                      cast<CXXRecordDecl>(target->getDeclContext()),
1801
23
                      DeclAccessPair::make(target, access),
1802
23
                      /*no instance context*/ QualType());
1803
23
  entity.setDiag(diag::err_access_friend_function)
1804
23
      << (method->getQualifier() ? 
method->getQualifierLoc().getSourceRange()21
1805
23
                                 : 
method->getNameInfo().getSourceRange()2
);
1806
1807
  // We need to bypass delayed-diagnostics because we might be called
1808
  // while the ParsingDeclarator is active.
1809
23
  EffectiveContext EC(CurContext);
1810
23
  switch (CheckEffectiveAccess(*this, EC, target->getLocation(), entity)) {
1811
8
  case ::AR_accessible: return Sema::AR_accessible;
1812
13
  case ::AR_inaccessible: return Sema::AR_inaccessible;
1813
2
  case ::AR_dependent: return Sema::AR_dependent;
1814
23
  }
1815
0
  llvm_unreachable("invalid access result");
1816
0
}
1817
1818
Sema::AccessResult Sema::CheckAddressOfMemberAccess(Expr *OvlExpr,
1819
1.65k
                                                    DeclAccessPair Found) {
1820
1.65k
  if (!getLangOpts().AccessControl ||
1821
1.65k
      Found.getAccess() == AS_none ||
1822
1.65k
      
Found.getAccess() == AS_public354
)
1823
1.55k
    return AR_accessible;
1824
1825
101
  OverloadExpr *Ovl = OverloadExpr::find(OvlExpr).Expression;
1826
101
  CXXRecordDecl *NamingClass = Ovl->getNamingClass();
1827
1828
101
  AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
1829
101
                      /*no instance context*/ QualType());
1830
101
  Entity.setDiag(diag::err_access)
1831
101
    << Ovl->getSourceRange();
1832
1833
101
  return CheckAccess(*this, Ovl->getNameLoc(), Entity);
1834
1.65k
}
1835
1836
/// Checks access for a hierarchy conversion.
1837
///
1838
/// \param ForceCheck true if this check should be performed even if access
1839
///     control is disabled;  some things rely on this for semantics
1840
/// \param ForceUnprivileged true if this check should proceed as if the
1841
///     context had no special privileges
1842
Sema::AccessResult Sema::CheckBaseClassAccess(SourceLocation AccessLoc,
1843
                                              QualType Base,
1844
                                              QualType Derived,
1845
                                              const CXXBasePath &Path,
1846
                                              unsigned DiagID,
1847
                                              bool ForceCheck,
1848
25.3k
                                              bool ForceUnprivileged) {
1849
25.3k
  if (!ForceCheck && 
!getLangOpts().AccessControl25.2k
)
1850
1.74k
    return AR_accessible;
1851
1852
23.5k
  if (Path.Access == AS_public)
1853
11.3k
    return AR_accessible;
1854
1855
12.2k
  CXXRecordDecl *BaseD, *DerivedD;
1856
12.2k
  BaseD = cast<CXXRecordDecl>(Base->castAs<RecordType>()->getDecl());
1857
12.2k
  DerivedD = cast<CXXRecordDecl>(Derived->castAs<RecordType>()->getDecl());
1858
1859
12.2k
  AccessTarget Entity(Context, AccessTarget::Base, BaseD, DerivedD,
1860
12.2k
                      Path.Access);
1861
12.2k
  if (DiagID)
1862
12.2k
    Entity.setDiag(DiagID) << Derived << Base;
1863
1864
12.2k
  if (ForceUnprivileged) {
1865
15
    switch (CheckEffectiveAccess(*this, EffectiveContext(),
1866
15
                                 AccessLoc, Entity)) {
1867
0
    case ::AR_accessible: return Sema::AR_accessible;
1868
15
    case ::AR_inaccessible: return Sema::AR_inaccessible;
1869
0
    case ::AR_dependent: return Sema::AR_dependent;
1870
15
    }
1871
0
    llvm_unreachable("unexpected result from CheckEffectiveAccess");
1872
0
  }
1873
12.2k
  return CheckAccess(*this, AccessLoc, Entity);
1874
12.2k
}
1875
1876
/// Checks access to all the declarations in the given result set.
1877
4.49M
void Sema::CheckLookupAccess(const LookupResult &R) {
1878
4.49M
  assert(getLangOpts().AccessControl
1879
4.49M
         && "performing access check without access control");
1880
0
  assert(R.getNamingClass() && "performing access check without naming class");
1881
1882
9.17M
  for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; 
++I4.67M
) {
1883
4.67M
    if (I.getAccess() != AS_public) {
1884
838k
      AccessTarget Entity(Context, AccessedEntity::Member,
1885
838k
                          R.getNamingClass(), I.getPair(),
1886
838k
                          R.getBaseObjectType());
1887
838k
      Entity.setDiag(diag::err_access);
1888
838k
      CheckAccess(*this, R.getNameLoc(), Entity);
1889
838k
    }
1890
4.67M
  }
1891
4.49M
}
1892
1893
/// Checks access to Target from the given class. The check will take access
1894
/// specifiers into account, but no member access expressions and such.
1895
///
1896
/// \param Target the declaration to check if it can be accessed
1897
/// \param NamingClass the class in which the lookup was started.
1898
/// \param BaseType type of the left side of member access expression.
1899
///        \p BaseType and \p NamingClass are used for C++ access control.
1900
///        Depending on the lookup case, they should be set to the following:
1901
///        - lhs.target (member access without a qualifier):
1902
///          \p BaseType and \p NamingClass are both the type of 'lhs'.
1903
///        - lhs.X::target (member access with a qualifier):
1904
///          BaseType is the type of 'lhs', NamingClass is 'X'
1905
///        - X::target (qualified lookup without member access):
1906
///          BaseType is null, NamingClass is 'X'.
1907
///        - target (unqualified lookup).
1908
///          BaseType is null, NamingClass is the parent class of 'target'.
1909
/// \return true if the Target is accessible from the Class, false otherwise.
1910
bool Sema::IsSimplyAccessible(NamedDecl *Target, CXXRecordDecl *NamingClass,
1911
17.1k
                              QualType BaseType) {
1912
  // Perform the C++ accessibility checks first.
1913
17.1k
  if (Target->isCXXClassMember() && 
NamingClass2.18k
) {
1914
2.14k
    if (!getLangOpts().CPlusPlus)
1915
0
      return false;
1916
    // The unprivileged access is AS_none as we don't know how the member was
1917
    // accessed, which is described by the access in DeclAccessPair.
1918
    // `IsAccessible` will examine the actual access of Target (i.e.
1919
    // Decl->getAccess()) when calculating the access.
1920
2.14k
    AccessTarget Entity(Context, AccessedEntity::Member, NamingClass,
1921
2.14k
                        DeclAccessPair::make(Target, AS_none), BaseType);
1922
2.14k
    EffectiveContext EC(CurContext);
1923
2.14k
    return ::IsAccessible(*this, EC, Entity) != ::AR_inaccessible;
1924
2.14k
  }
1925
1926
14.9k
  if (ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(Target)) {
1927
    // @public and @package ivars are always accessible.
1928
76
    if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Public ||
1929
76
        
Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Package66
)
1930
10
      return true;
1931
1932
    // If we are inside a class or category implementation, determine the
1933
    // interface we're in.
1934
66
    ObjCInterfaceDecl *ClassOfMethodDecl = nullptr;
1935
66
    if (ObjCMethodDecl *MD = getCurMethodDecl())
1936
56
      ClassOfMethodDecl =  MD->getClassInterface();
1937
10
    else if (FunctionDecl *FD = getCurFunctionDecl()) {
1938
10
      if (ObjCImplDecl *Impl
1939
10
            = dyn_cast<ObjCImplDecl>(FD->getLexicalDeclContext())) {
1940
0
        if (ObjCImplementationDecl *IMPD
1941
0
              = dyn_cast<ObjCImplementationDecl>(Impl))
1942
0
          ClassOfMethodDecl = IMPD->getClassInterface();
1943
0
        else if (ObjCCategoryImplDecl* CatImplClass
1944
0
                   = dyn_cast<ObjCCategoryImplDecl>(Impl))
1945
0
          ClassOfMethodDecl = CatImplClass->getClassInterface();
1946
0
      }
1947
10
    }
1948
1949
    // If we're not in an interface, this ivar is inaccessible.
1950
66
    if (!ClassOfMethodDecl)
1951
10
      return false;
1952
1953
    // If we're inside the same interface that owns the ivar, we're fine.
1954
56
    if (declaresSameEntity(ClassOfMethodDecl, Ivar->getContainingInterface()))
1955
50
      return true;
1956
1957
    // If the ivar is private, it's inaccessible.
1958
6
    if (Ivar->getCanonicalAccessControl() == ObjCIvarDecl::Private)
1959
3
      return false;
1960
1961
3
    return Ivar->getContainingInterface()->isSuperClassOf(ClassOfMethodDecl);
1962
6
  }
1963
1964
14.8k
  return true;
1965
14.9k
}