@@ -2656,188 +2656,122 @@ bool Sema::isCurrentClassNameTypo(IdentifierInfo *&II, const CXXScopeSpec *SS) {
26562656 return false;
26572657}
26582658
2659- /// Determine whether the given class is a base class of the given
2660- /// class, including looking at dependent bases.
2661- static bool findCircularInheritance(const CXXRecordDecl *Class,
2662- const CXXRecordDecl *Current) {
2663- SmallVector<const CXXRecordDecl*, 8> Queue;
2664-
2665- Class = Class->getCanonicalDecl();
2666- while (true) {
2667- for (const auto &I : Current->bases()) {
2668- CXXRecordDecl *Base = I.getType()->getAsCXXRecordDecl();
2669- if (!Base)
2670- continue;
2671-
2672- Base = Base->getDefinition();
2673- if (!Base)
2674- continue;
2675-
2676- if (Base->getCanonicalDecl() == Class)
2677- return true;
2678-
2679- Queue.push_back(Base);
2680- }
2681-
2682- if (Queue.empty())
2683- return false;
2684-
2685- Current = Queue.pop_back_val();
2686- }
2687-
2688- return false;
2689- }
2690-
26912659/// Check the validity of a C++ base class specifier.
26922660///
26932661/// \returns a new CXXBaseSpecifier if well-formed, emits diagnostics
26942662/// and returns NULL otherwise.
2695- CXXBaseSpecifier *
2696- Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
2697- SourceRange SpecifierRange,
2698- bool Virtual, AccessSpecifier Access,
2699- TypeSourceInfo *TInfo,
2700- SourceLocation EllipsisLoc) {
2701- // In HLSL, unspecified class access is public rather than private.
2702- if (getLangOpts().HLSL && Class->getTagKind() == TagTypeKind::Class &&
2703- Access == AS_none)
2704- Access = AS_public;
2705-
2663+ CXXBaseSpecifier *Sema::CheckBaseSpecifier(CXXRecordDecl *Class,
2664+ SourceRange SpecifierRange,
2665+ bool Virtual, AccessSpecifier Access,
2666+ TypeSourceInfo *TInfo,
2667+ SourceLocation EllipsisLoc) {
27062668 QualType BaseType = TInfo->getType();
2669+ SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
27072670 if (BaseType->containsErrors()) {
27082671 // Already emitted a diagnostic when parsing the error type.
27092672 return nullptr;
27102673 }
2711- // C++ [class.union]p1:
2712- // A union shall not have base classes.
2713- if (Class->isUnion()) {
2714- Diag(Class->getLocation(), diag::err_base_clause_on_union)
2715- << SpecifierRange;
2716- return nullptr;
2717- }
27182674
2719- if (EllipsisLoc.isValid() &&
2720- !TInfo->getType()->containsUnexpandedParameterPack()) {
2675+ if (EllipsisLoc.isValid() && !BaseType->containsUnexpandedParameterPack()) {
27212676 Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
27222677 << TInfo->getTypeLoc().getSourceRange();
27232678 EllipsisLoc = SourceLocation();
27242679 }
27252680
2726- SourceLocation BaseLoc = TInfo->getTypeLoc().getBeginLoc();
2727-
2728- if (BaseType->isDependentType()) {
2729- // Make sure that we don't have circular inheritance among our dependent
2730- // bases. For non-dependent bases, the check for completeness below handles
2731- // this.
2732- if (CXXRecordDecl *BaseDecl = BaseType->getAsCXXRecordDecl()) {
2733- if (BaseDecl->getCanonicalDecl() == Class->getCanonicalDecl() ||
2734- ((BaseDecl = BaseDecl->getDefinition()) &&
2735- findCircularInheritance(Class, BaseDecl))) {
2736- Diag(BaseLoc, diag::err_circular_inheritance)
2737- << BaseType << Context.getTypeDeclType(Class);
2738-
2739- if (BaseDecl->getCanonicalDecl() != Class->getCanonicalDecl())
2740- Diag(BaseDecl->getLocation(), diag::note_previous_decl)
2741- << BaseType;
2681+ auto *BaseDecl =
2682+ dyn_cast_if_present<CXXRecordDecl>(computeDeclContext(BaseType));
2683+ // C++ [class.derived.general]p2:
2684+ // A class-or-decltype shall denote a (possibly cv-qualified) class type
2685+ // that is not an incompletely defined class; any cv-qualifiers are
2686+ // ignored.
2687+ if (BaseDecl) {
2688+ // C++ [class.union.general]p4:
2689+ // [...] A union shall not be used as a base class.
2690+ if (BaseDecl->isUnion()) {
2691+ Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
2692+ return nullptr;
2693+ }
27422694
2743- return nullptr;
2695+ // For the MS ABI, propagate DLL attributes to base class templates.
2696+ if (Context.getTargetInfo().getCXXABI().isMicrosoft() ||
2697+ Context.getTargetInfo().getTriple().isPS()) {
2698+ if (Attr *ClassAttr = getDLLAttr(Class)) {
2699+ if (auto *BaseSpec =
2700+ dyn_cast<ClassTemplateSpecializationDecl>(BaseDecl)) {
2701+ propagateDLLAttrToBaseClassTemplate(Class, ClassAttr, BaseSpec,
2702+ BaseLoc);
2703+ }
27442704 }
27452705 }
27462706
2707+ if (RequireCompleteType(BaseLoc, BaseType, diag::err_incomplete_base_class,
2708+ SpecifierRange)) {
2709+ Class->setInvalidDecl();
2710+ return nullptr;
2711+ }
2712+
2713+ BaseDecl = BaseDecl->getDefinition();
2714+ assert(BaseDecl && "Base type is not incomplete, but has no definition");
2715+
2716+ // Microsoft docs say:
2717+ // "If a base-class has a code_seg attribute, derived classes must have the
2718+ // same attribute."
2719+ const auto *BaseCSA = BaseDecl->getAttr<CodeSegAttr>();
2720+ const auto *DerivedCSA = Class->getAttr<CodeSegAttr>();
2721+ if ((DerivedCSA || BaseCSA) &&
2722+ (!BaseCSA || !DerivedCSA ||
2723+ BaseCSA->getName() != DerivedCSA->getName())) {
2724+ Diag(Class->getLocation(), diag::err_mismatched_code_seg_base);
2725+ Diag(BaseDecl->getLocation(), diag::note_base_class_specified_here)
2726+ << BaseDecl;
2727+ return nullptr;
2728+ }
2729+
2730+ // A class which contains a flexible array member is not suitable for use as
2731+ // a base class:
2732+ // - If the layout determines that a base comes before another base,
2733+ // the flexible array member would index into the subsequent base.
2734+ // - If the layout determines that base comes before the derived class,
2735+ // the flexible array member would index into the derived class.
2736+ if (BaseDecl->hasFlexibleArrayMember()) {
2737+ Diag(BaseLoc, diag::err_base_class_has_flexible_array_member)
2738+ << BaseDecl->getDeclName();
2739+ return nullptr;
2740+ }
2741+
2742+ // C++ [class]p3:
2743+ // If a class is marked final and it appears as a base-type-specifier in
2744+ // base-clause, the program is ill-formed.
2745+ if (FinalAttr *FA = BaseDecl->getAttr<FinalAttr>()) {
2746+ Diag(BaseLoc, diag::err_class_marked_final_used_as_base)
2747+ << BaseDecl->getDeclName() << FA->isSpelledAsSealed();
2748+ Diag(BaseDecl->getLocation(), diag::note_entity_declared_at)
2749+ << BaseDecl->getDeclName() << FA->getRange();
2750+ return nullptr;
2751+ }
2752+
2753+ // If the base class is invalid the derived class is as well.
2754+ if (BaseDecl->isInvalidDecl())
2755+ Class->setInvalidDecl();
2756+ } else if (BaseType->isDependentType()) {
27472757 // Make sure that we don't make an ill-formed AST where the type of the
27482758 // Class is non-dependent and its attached base class specifier is an
27492759 // dependent type, which violates invariants in many clang code paths (e.g.
27502760 // constexpr evaluator). If this case happens (in errory-recovery mode), we
27512761 // explicitly mark the Class decl invalid. The diagnostic was already
27522762 // emitted.
2753- if (!Class->getTypeForDecl()->isDependentType ())
2763+ if (!Class->isDependentContext ())
27542764 Class->setInvalidDecl();
2755- return new (Context) CXXBaseSpecifier(
2756- SpecifierRange, Virtual, Class->getTagKind() == TagTypeKind::Class,
2757- Access, TInfo, EllipsisLoc);
2758- }
2759-
2760- // Base specifiers must be record types.
2761- if (!BaseType->isRecordType()) {
2765+ } else {
2766+ // The base class is some non-dependent non-class type.
27622767 Diag(BaseLoc, diag::err_base_must_be_class) << SpecifierRange;
27632768 return nullptr;
27642769 }
27652770
2766- // C++ [class.union]p1:
2767- // A union shall not be used as a base class.
2768- if (BaseType->isUnionType()) {
2769- Diag(BaseLoc, diag::err_union_as_base_class) << SpecifierRange;
2770- return nullptr;
2771- }
2772-
2773- // For the MS ABI, propagate DLL attributes to base class templates.
2774- if (Context.getTargetInfo().getCXXABI().isMicrosoft() ||
2775- Context.getTargetInfo().getTriple().isPS()) {
2776- if (Attr *ClassAttr = getDLLAttr(Class)) {
2777- if (auto *BaseTemplate = dyn_cast_or_null<ClassTemplateSpecializationDecl>(
2778- BaseType->getAsCXXRecordDecl())) {
2779- propagateDLLAttrToBaseClassTemplate(Class, ClassAttr, BaseTemplate,
2780- BaseLoc);
2781- }
2782- }
2783- }
2784-
2785- // C++ [class.derived]p2:
2786- // The class-name in a base-specifier shall not be an incompletely
2787- // defined class.
2788- if (RequireCompleteType(BaseLoc, BaseType,
2789- diag::err_incomplete_base_class, SpecifierRange)) {
2790- Class->setInvalidDecl();
2791- return nullptr;
2792- }
2793-
2794- // If the base class is polymorphic or isn't empty, the new one is/isn't, too.
2795- RecordDecl *BaseDecl = BaseType->castAs<RecordType>()->getDecl();
2796- assert(BaseDecl && "Record type has no declaration");
2797- BaseDecl = BaseDecl->getDefinition();
2798- assert(BaseDecl && "Base type is not incomplete, but has no definition");
2799- CXXRecordDecl *CXXBaseDecl = cast<CXXRecordDecl>(BaseDecl);
2800- assert(CXXBaseDecl && "Base type is not a C++ type");
2801-
2802- // Microsoft docs say:
2803- // "If a base-class has a code_seg attribute, derived classes must have the
2804- // same attribute."
2805- const auto *BaseCSA = CXXBaseDecl->getAttr<CodeSegAttr>();
2806- const auto *DerivedCSA = Class->getAttr<CodeSegAttr>();
2807- if ((DerivedCSA || BaseCSA) &&
2808- (!BaseCSA || !DerivedCSA || BaseCSA->getName() != DerivedCSA->getName())) {
2809- Diag(Class->getLocation(), diag::err_mismatched_code_seg_base);
2810- Diag(CXXBaseDecl->getLocation(), diag::note_base_class_specified_here)
2811- << CXXBaseDecl;
2812- return nullptr;
2813- }
2814-
2815- // A class which contains a flexible array member is not suitable for use as a
2816- // base class:
2817- // - If the layout determines that a base comes before another base,
2818- // the flexible array member would index into the subsequent base.
2819- // - If the layout determines that base comes before the derived class,
2820- // the flexible array member would index into the derived class.
2821- if (CXXBaseDecl->hasFlexibleArrayMember()) {
2822- Diag(BaseLoc, diag::err_base_class_has_flexible_array_member)
2823- << CXXBaseDecl->getDeclName();
2824- return nullptr;
2825- }
2826-
2827- // C++ [class]p3:
2828- // If a class is marked final and it appears as a base-type-specifier in
2829- // base-clause, the program is ill-formed.
2830- if (FinalAttr *FA = CXXBaseDecl->getAttr<FinalAttr>()) {
2831- Diag(BaseLoc, diag::err_class_marked_final_used_as_base)
2832- << CXXBaseDecl->getDeclName()
2833- << FA->isSpelledAsSealed();
2834- Diag(CXXBaseDecl->getLocation(), diag::note_entity_declared_at)
2835- << CXXBaseDecl->getDeclName() << FA->getRange();
2836- return nullptr;
2837- }
2838-
2839- if (BaseDecl->isInvalidDecl())
2840- Class->setInvalidDecl();
2771+ // In HLSL, unspecified class access is public rather than private.
2772+ if (getLangOpts().HLSL && Class->getTagKind() == TagTypeKind::Class &&
2773+ Access == AS_none)
2774+ Access = AS_public;
28412775
28422776 // Create the base specifier.
28432777 return new (Context) CXXBaseSpecifier(
@@ -2887,13 +2821,20 @@ BaseResult Sema::ActOnBaseSpecifier(Decl *classdecl, SourceRange SpecifierRange,
28872821 UPPC_BaseType))
28882822 return true;
28892823
2824+ // C++ [class.union.general]p4:
2825+ // [...] A union shall not have base classes.
2826+ if (Class->isUnion()) {
2827+ Diag(Class->getLocation(), diag::err_base_clause_on_union)
2828+ << SpecifierRange;
2829+ return true;
2830+ }
2831+
28902832 if (CXXBaseSpecifier *BaseSpec = CheckBaseSpecifier(Class, SpecifierRange,
28912833 Virtual, Access, TInfo,
28922834 EllipsisLoc))
28932835 return BaseSpec;
2894- else
2895- Class->setInvalidDecl();
28962836
2837+ Class->setInvalidDecl();
28972838 return true;
28982839}
28992840
0 commit comments