diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h index 99a0d204861e0..5ef12b8ece422 100644 --- a/clang/include/clang/AST/Type.h +++ b/clang/include/clang/AST/Type.h @@ -2479,6 +2479,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { bool isIncompleteOrSizelessType() const { return isIncompleteType() || isSizelessType() || isFunctionType(); } + /* TO_UPSTREAM(BoundsSafety) OFF*/ /// \returns True if the type is incomplete and it is also a type that /// cannot be completed by a later type definition. @@ -2495,11 +2496,10 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase { /// // This decl has type 'char[]' which is incomplete and cannot be later /// // completed by another by another type declaration. /// extern char foo[]; - /// // This decl how has complete type 'char[5]'. + /// // This decl now has complete type 'char[5]'. /// char foo[5]; // foo has a complete type /// \endcode - bool isIncompletableIncompleteType() const; - /* TO_UPSTREAM(BoundsSafety) OFF*/ + bool isAlwaysIncompleteType() const; /// Determine whether this type is an object type. bool isObjectType() const { @@ -3690,9 +3690,7 @@ class CountAttributedType final return T->getTypeClass() == CountAttributed; } - /* TO_UPSTREAM(BoundsSafety) ON*/ - StringRef GetAttributeName(bool WithMacroPrefix) const; - /* TO_UPSTREAM(BoundsSafety) OFF*/ + StringRef getAttributeName(bool WithMacroPrefix) const; }; /* TO_UPSTREAM(BoundsSafety) ON */ diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td index b30f330ecb2c1..7da0fb6b854f4 100644 --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -6790,6 +6790,30 @@ def err_counted_by_attr_pointee_unknown_size : Error< "%select{|. This will be an error in a future compiler version}3" "" "}2">; +def err_counted_by_on_incomplete_type_on_assign : Error < + "cannot %select{" + "assign to %select{object|'%1'}2 with|" // AA_Assigning, + "pass argument to %select{parameter|parameter '%1'}2 with|" // AA_Passing, + "return|" // AA_Returning, + "convert to|" // AA_Converting (UNUSED) + "%select{|implicitly }3initialize %select{object|'%1'}2 with|" // AA_Initializing, + "pass argument to parameter with|" // AA_Sending (UNUSED) + "cast to|" // AA_Casting (UNUSED) + "pass argument to parameter with" // AA_Passing_CFAudited (UNUSED) + "}0 '%5' attributed type %4 because the pointee type %6 is incomplete">; + +def err_counted_by_on_incomplete_type_on_use : Error < + "cannot %select{" + "use '%1' with '%4' attributed|" // Generic expr + "call '%1' with '%4' attributed return" // CallExpr + "}0 type %2 because the pointee type %3 is incomplete">; + +def note_counted_by_consider_completing_pointee_ty : Note< + "consider providing a complete definition for %0">; + +def note_counted_by_consider_using_sized_by : Note< + "consider using '__sized_by%select{|_or_null}0' instead of " + "'__counted_by%select{|_or_null}0'">; def warn_counted_by_attr_elt_type_unknown_size : Warning, @@ -12895,8 +12919,7 @@ def err_bounds_safety_counted_by_on_incomplete_type_on_func_def : Error< " '%3'" // named parameter "}2 with" "}1 type %4 on a function definition because the pointee type %5 is " - "incomplete; consider providing a complete definition for %5 before the " - "function body or using the '__sized_by%select{|_or_null}6' attribute" + "incomplete" >; def err_bounds_safety_counted_by_on_incomplete_type_on_var_decl : Error< diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index e8ea9e7c93976..20769de41c6f5 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2263,7 +2263,6 @@ class Sema final : public SemaBase { bool CheckCountedByAttrOnField(FieldDecl *FD, Expr *E, bool CountInBytes, bool OrNull); - /* TO_UPSTREAM(BoundsSafety) ON*/ /// Perform Bounds Safety Semantic checks for assigning to a `__counted_by` or /// `__counted_by_or_null` pointer type \param LHSTy. /// @@ -2285,28 +2284,6 @@ class Sema final : public SemaBase { SourceLocation Loc, const ValueDecl *Assignee, bool ShowFullyQualifiedAssigneeName); - /// Perform Checks for assigning to a `__counted_by` or - /// `__counted_by_or_null` pointer type \param LHSTy where the pointee type - /// is incomplete which is invalid. - /// - /// \param LHSTy The type being assigned to. Checks will only be performed if - /// the type is a `counted_by` or `counted_by_or_null ` pointer. - /// \param RHSExpr The expression being assigned from. - /// \param Action The type assignment being performed - /// \param Loc The SourceLocation to use for error diagnostics - /// \param Assignee The ValueDecl being assigned. This is used to compute - /// the name of the assignee. If the assignee isn't known this can - /// be set to nullptr. - /// \param ShowFullyQualifiedAssigneeName If set to true when using \p - /// Assignee to compute the name of the assignee use the fully - /// qualified name, otherwise use the unqualified name. - /// - /// \returns True iff no diagnostic where emitted, false otherwise. - bool BoundsSafetyCheckAssignmentToCountAttrPtrWithIncompletePointeeTy( - QualType LHSTy, Expr *RHSExpr, AssignmentAction Action, - SourceLocation Loc, const ValueDecl *Assignee, - bool ShowFullyQualifiedAssigneeName); - /// Perform Bounds Safety Semantic checks for initializing a Bounds Safety /// pointer. /// @@ -2323,6 +2300,15 @@ class Sema final : public SemaBase { AssignmentAction Action, QualType LHSType, Expr *RHSExpr); + /// Perform Bounds Safety semantic checks for uses of invalid uses counted_by + /// or counted_by_or_null pointers in \param E. + /// + /// \param E the expression to check + /// + /// \returns True iff no diagnostic where emitted, false otherwise. + bool BoundsSafetyCheckUseOfCountAttrPtr(const Expr *E); + + /* TO_UPSTREAM(BoundsSafety) ON*/ /// Perform Bounds Safety semantic checks on function parameters on a function /// definition. This only performs checks that can be made by looking at /// \param PVD in isolation (i.e. not looking at other parameters in the @@ -2351,14 +2337,6 @@ class Sema final : public SemaBase { /// \returns True iff no diagnostic where emitted, false otherwise. bool BoundsSafetyCheckReturnTyForFunctionDef(FunctionDecl *FD); - /// Perform Bounds Safety semantic checks for uses of invalid uses counted_by - /// or counted_by_or_null pointers in \param E. - /// - /// \param E the expression to check - /// - /// \returns True iff no diagnostic where emitted, false otherwise. - bool BoundsSafetyCheckUseOfCountAttrPtr(Expr *E); - /// Perform Bounds Safety semantic checks on variable declaration \param VD. /// /// \param VD The VarDecl to check diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp index e4dfd989ab2e7..5aaf444110d53 100644 --- a/clang/lib/AST/Type.cpp +++ b/clang/lib/AST/Type.cpp @@ -2591,6 +2591,22 @@ bool Type::isIncompleteType(NamedDecl **Def) const { } } +bool Type::isAlwaysIncompleteType() const { + if (!isIncompleteType()) + return false; + + // Forward declarations of structs, classes, enums, and unions could be later + // completed in a compilation unit by providing a type definition. + if (getAsTagDecl()) + return false; + + // Other types are incompletable. + // + // E.g. `char[]` and `void`. The type is incomplete and no future + // type declarations can make the type complete. + return true; +} + bool Type::isSizelessBuiltinType() const { if (isSizelessVectorType()) return true; @@ -2708,22 +2724,6 @@ bool Type::isSizeMeaningless() const { return true; return false; } - -bool Type::isIncompletableIncompleteType() const { - if (!isIncompleteType()) - return false; - - // Forward declarations of structs, classes, enums, and unions could be later - // completed in a compilation unit by providing a definition. - if (isStructureOrClassType() || isEnumeralType() || isUnionType()) - return false; - - // Other types are incompletable. - // - // E.g. `char[]` and `void`. The type is incomplete and no future - // type declarations can make the type complete. - return true; -} /* TO_UPSTREAM(BoundsSafety) OFF*/ QualType Type::getSizelessVectorEltType(const ASTContext &Ctx) const { @@ -4072,8 +4072,11 @@ CountAttributedType::CountAttributedType( DeclSlot[i] = CoupledDecls[i]; } -/* TO_UPSTREAM(BoundsSafety) ON*/ -StringRef CountAttributedType::GetAttributeName(bool WithMacroPrefix) const { +StringRef CountAttributedType::getAttributeName(bool WithMacroPrefix) const { +// TODO: This method isn't really ideal because it doesn't return the spelling +// of the attribute that was used in the user's code. This method is used for +// diagnostics so the fact it doesn't use the spelling of the attribute in +// the user's code could be confusing (#113585). #define ENUMERATE_ATTRS(PREFIX) \ do { \ if (isCountInBytes()) { \ @@ -4094,6 +4097,7 @@ StringRef CountAttributedType::GetAttributeName(bool WithMacroPrefix) const { #undef ENUMERATE_ATTRS } +/* TO_UPSTREAM(BoundsSafety) ON*/ DynamicRangePointerType::DynamicRangePointerType( QualType PointerTy, QualType CanPointerTy, Expr *StartPtr, Expr *EndPtr, ArrayRef StartPtrDecls, diff --git a/clang/lib/Sema/SemaBoundsSafety.cpp b/clang/lib/Sema/SemaBoundsSafety.cpp index 403829cd723bb..b343cc8e3ba44 100644 --- a/clang/lib/Sema/SemaBoundsSafety.cpp +++ b/clang/lib/Sema/SemaBoundsSafety.cpp @@ -154,7 +154,36 @@ bool Sema::CheckCountedByAttrOnField(FieldDecl *FD, Expr *E, bool CountInBytes, // only `PointeeTy->isStructureTypeWithFlexibleArrayMember()` is reachable // when `FieldTy->isArrayType()`. bool ShouldWarn = false; - if (PointeeTy->isIncompleteType() && !CountInBytes) { + if (PointeeTy->isAlwaysIncompleteType() && !CountInBytes) { + // In general using `counted_by` or `counted_by_or_null` on + // pointers where the pointee is an incomplete type are problematic. This is + // because it isn't possible to compute the pointer's bounds without knowing + // the pointee type size. At the same time it is common to forward declare + // types in header files. + // + // E.g.: + // + // struct Handle; + // struct Wrapper { + // size_t size; + // struct Handle* __counted_by(count) handles; + // } + // + // To allow the above code pattern but still prevent the pointee type from + // being incomplete in places where bounds checks are needed the following + // scheme is used: + // + // * When the pointee type might not always be an incomplete type (i.e. + // a type that is currently incomplete but might be completed later + // on in the translation unit) the attribute is allowed by this method + // but later uses of the FieldDecl are checked that the pointee type + // is complete see `BoundsSafetyCheckAssignmentToCountAttrPtr`, + // `BoundsSafetyCheckInitialization`, and + // `BoundsSafetyCheckUseOfCountAttrPtr` + // + // * When the pointee type is always an incomplete type (e.g. + // `void`) the attribute is disallowed by this method because we know the + // type can never be completed so there's no reason to allow it. InvalidTypeKind = CountedByInvalidPointeeTypeKind::INCOMPLETE; } else if (PointeeTy->isSizelessType()) { InvalidTypeKind = CountedByInvalidPointeeTypeKind::SIZELESS; @@ -313,7 +342,7 @@ static SourceRange SourceRangeFor(const CountAttributedType *CATy, Sema &S) { // Special case: When the character is part of a macro the Token we get // is the whole macro name (e.g. `__counted_by`). if (LastAttrCharToken.getRawIdentifier() != - CATy->GetAttributeName(/*WithMacroPrefix=*/true)) + CATy->getAttributeName(/*WithMacroPrefix=*/true)) return Fallback; // Found the beginning of the `__counted_by` macro @@ -344,7 +373,7 @@ static SourceRange SourceRangeFor(const CountAttributedType *CATy, Sema &S) { // +1 is for `(` const ssize_t NonAffixedSkipCount = - CATy->GetAttributeName(/*WithMacroPrefix=*/false).size() + 1; + CATy->getAttributeName(/*WithMacroPrefix=*/false).size() + 1; auto MaybeNonAffixedBeginToken = FetchIdentifierTokenFromOffset(-NonAffixedSkipCount); if (!MaybeNonAffixedBeginToken) @@ -352,7 +381,7 @@ static SourceRange SourceRangeFor(const CountAttributedType *CATy, Sema &S) { auto NonAffixedBeginToken = MaybeNonAffixedBeginToken.value(); if (NonAffixedBeginToken.getRawIdentifier() == - CATy->GetAttributeName(/*WithMacroPrefix=*/false)) { + CATy->getAttributeName(/*WithMacroPrefix=*/false)) { // Found the beginning of the `counted_by`-like attribute auto SL = NonAffixedBeginToken.getLocation(); @@ -371,13 +400,13 @@ static SourceRange SourceRangeFor(const CountAttributedType *CATy, Sema &S) { // | | // ---------------- std::string AffixedTokenStr = - (llvm::Twine("__") + CATy->GetAttributeName(/*WithMacroPrefix=*/false) + + (llvm::Twine("__") + CATy->getAttributeName(/*WithMacroPrefix=*/false) + llvm::Twine("__")) .str(); // +1 is for `(` // +4 is for the 4 `_` characters const ssize_t AffixedSkipCount = - CATy->GetAttributeName(/*WithMacroPrefix=*/false).size() + 1 + 4; + CATy->getAttributeName(/*WithMacroPrefix=*/false).size() + 1 + 4; auto MaybeAffixedBeginToken = FetchIdentifierTokenFromOffset(-AffixedSkipCount); if (!MaybeAffixedBeginToken) @@ -396,90 +425,99 @@ static SourceRange SourceRangeFor(const CountAttributedType *CATy, Sema &S) { return SourceRange(SL, MaybeRParenTok->getLocation()); } +/* TO_UPSTREAM(BoundsSafety) OFF*/ static void EmitIncompleteCountedByPointeeNotes(Sema &S, const CountAttributedType *CATy, - NamedDecl *IncompleteTyDecl, - bool NoteAttrLocation = true) { + NamedDecl *IncompleteTyDecl) { assert(IncompleteTyDecl == nullptr || isa(IncompleteTyDecl)); - if (NoteAttrLocation) { - // Note where the attribute is declared - auto AttrSrcRange = SourceRangeFor(CATy, S); - S.Diag(AttrSrcRange.getBegin(), diag::note_named_attribute) - << CATy->GetAttributeName(/*WithMacroPrefix=*/true) << AttrSrcRange; + if (IncompleteTyDecl) { + // Suggest completing the pointee type if its a named typed (i.e. + // IncompleteTyDecl isn't nullptr). Suggest this first as it is more likely + // to be the correct fix. + // + // Note the `IncompleteTyDecl` type is the underlying type which might not + // be the same as `CATy->getPointeeType()` which could be a typedef. + // + // The diagnostic printed will be at the location of the underlying type but + // the diagnostic text will print the type of `CATy->getPointeeType()` which + // could be a typedef name rather than the underlying type. This is ok + // though because the diagnostic will print the underlying type name too. + S.Diag(IncompleteTyDecl->getBeginLoc(), + diag::note_counted_by_consider_completing_pointee_ty) + << CATy->getPointeeType(); } - if (!IncompleteTyDecl) - return; - - // If there's an associated forward declaration display it to emphasize - // why the type is incomplete (all we have is a forward declaration). - - // Note the `IncompleteTyDecl` type is the underlying type which might not - // be the same as `CATy->getPointeeType()` which could be a typedef. + // Suggest using __sized_by(_or_null) instead of __counted_by(_or_null) as + // __sized_by(_or_null) doesn't have the complete type restriction. // - // The diagnostic printed will be at the location of the underlying type but - // the diagnostic text will print the type of `CATy->getPointeeType()` which - // could be a typedef name rather than the underlying type. This is ok - // though because the diagnostic will print the underlying type name too. - // E.g: + // We use the source range of the expression on the CountAttributedType as an + // approximation for the source range of the attribute. This isn't quite right + // but isn't easy to fix right now. // - // `forward declaration of 'Incomplete_Struct_t' - // (aka 'struct IncompleteStructTy')` + // TODO: Implement logic to find the relevant TypeLoc for the attribute and + // get the SourceRange from that (#113582). // - // If this ends up being confusing we could emit a second diagnostic (one - // explaining where the typedef is) but that seems overly verbose. + // TODO: We should emit a fix-it here. - S.Diag(IncompleteTyDecl->getBeginLoc(), diag::note_forward_declaration) - << CATy->getPointeeType(); + /* TO_UPSTREAM(BoundsSafety) ON*/ + // TODO: Upstream probably won't accept `SourceRangeFor` so we should consider + // removing it and its related tests. + // SourceRange AttrSrcRange = CATy->getCountExpr()->getSourceRange(); + SourceRange AttrSrcRange = SourceRangeFor(CATy, S); + /* TO_UPSTREAM(BoundsSafety) OFF*/ + S.Diag(AttrSrcRange.getBegin(), diag::note_counted_by_consider_using_sized_by) + << CATy->isOrNull() << AttrSrcRange; } -static bool -HasCountedByAttrOnIncompletePointee(QualType Ty, NamedDecl **ND, - const CountAttributedType **CATyOut, - QualType *PointeeTyOut) { +static std::tuple +GetCountedByAttrOnIncompletePointee(QualType Ty, NamedDecl **ND) { auto *CATy = Ty->getAs(); - if (!CATy) - return false; - // Incomplete pointee type is only a problem for // counted_by/counted_by_or_null - if (CATy->isCountInBytes()) - return false; + if (!CATy || CATy->isCountInBytes()) + return {}; auto PointeeTy = CATy->getPointeeType(); - if (PointeeTy.isNull()) - return false; // Reachable? + if (PointeeTy.isNull()) { + // Reachable if `CountAttributedType` wraps an IncompleteArrayType + return {}; + } if (!PointeeTy->isIncompleteType(ND)) - return false; + return {}; - if (CATyOut) - *CATyOut = CATy; - if (PointeeTyOut) - *PointeeTyOut = PointeeTy; - return true; + return {CATy, PointeeTy}; } -bool Sema::BoundsSafetyCheckAssignmentToCountAttrPtrWithIncompletePointeeTy( - QualType LHSTy, Expr *RHSExpr, AssignmentAction Action, SourceLocation Loc, - const ValueDecl *Assignee, bool ShowFullyQualifiedAssigneeName) { +/// Perform Checks for assigning to a `__counted_by` or +/// `__counted_by_or_null` pointer type \param LHSTy where the pointee type +/// is incomplete which is invalid. +/// +/// \param S The Sema instance. +/// \param LHSTy The type being assigned to. Checks will only be performed if +/// the type is a `counted_by` or `counted_by_or_null ` pointer. +/// \param RHSExpr The expression being assigned from. +/// \param Action The type assignment being performed +/// \param Loc The SourceLocation to use for error diagnostics +/// \param Assignee The ValueDecl being assigned. This is used to compute +/// the name of the assignee. If the assignee isn't known this can +/// be set to nullptr. +/// \param ShowFullyQualifiedAssigneeName If set to true when using \p +/// Assignee to compute the name of the assignee use the fully +/// qualified name, otherwise use the unqualified name. +/// +/// \returns True iff no diagnostic where emitted, false otherwise. +static bool CheckAssignmentToCountAttrPtrWithIncompletePointeeTy( + Sema &S, QualType LHSTy, Expr *RHSExpr, AssignmentAction Action, + SourceLocation Loc, const ValueDecl *Assignee, + bool ShowFullyQualifiedAssigneeName) { NamedDecl *IncompleteTyDecl = nullptr; - const CountAttributedType *CATy = nullptr; - QualType PointeeTy; - if (!HasCountedByAttrOnIncompletePointee(LHSTy, &IncompleteTyDecl, &CATy, - &PointeeTy)) + auto [CATy, PointeeTy] = + GetCountedByAttrOnIncompletePointee(LHSTy, &IncompleteTyDecl); + if (!CATy) return true; - assert(CATy && !CATy->isCountInBytes() && !PointeeTy.isNull()); - - // It's not expected that the diagnostic be emitted in these cases. - // It's not necessarily a problem but we should catch when this starts - // to happen. - assert(Action != AssignmentAction::Converting && - Action != AssignmentAction::Sending && - Action != AssignmentAction::Casting && - Action != AssignmentAction::Passing_CFAudited); std::string AssigneeStr; if (Assignee) { @@ -489,123 +527,90 @@ bool Sema::BoundsSafetyCheckAssignmentToCountAttrPtrWithIncompletePointeeTy( AssigneeStr = Assignee->getNameAsString(); } } - { - auto D = - Diag(Loc, - diag::err_bounds_safety_counted_by_on_incomplete_type_on_assign) - << /*0*/ (int)Action << /*1*/ AssigneeStr - << /*2*/ (AssigneeStr.size() > 0) - << /*3*/ isa(RHSExpr) << /*4*/ LHSTy - << /*5*/ CATy->GetAttributeName(/*WithMacroPrefix=*/true) - << /*6*/ PointeeTy << /*7*/ CATy->isOrNull(); - - if (RHSExpr->getSourceRange().isValid()) - D << RHSExpr->getSourceRange(); - } - EmitIncompleteCountedByPointeeNotes(*this, CATy, IncompleteTyDecl); + S.Diag(Loc, diag::err_counted_by_on_incomplete_type_on_assign) + << static_cast(Action) << AssigneeStr << (AssigneeStr.size() > 0) + << isa(RHSExpr) << LHSTy + << CATy->getAttributeName(/*WithMacroPrefix=*/true) << PointeeTy + << CATy->isOrNull() << RHSExpr->getSourceRange(); + + EmitIncompleteCountedByPointeeNotes(S, CATy, IncompleteTyDecl); return false; // check failed } bool Sema::BoundsSafetyCheckAssignmentToCountAttrPtr( QualType LHSTy, Expr *RHSExpr, AssignmentAction Action, SourceLocation Loc, const ValueDecl *Assignee, bool ShowFullyQualifiedAssigneeName) { - if (!getLangOpts().hasBoundsSafety()) - return true; - - return BoundsSafetyCheckAssignmentToCountAttrPtrWithIncompletePointeeTy( - LHSTy, RHSExpr, Action, Loc, Assignee, ShowFullyQualifiedAssigneeName); + return CheckAssignmentToCountAttrPtrWithIncompletePointeeTy( + *this, LHSTy, RHSExpr, Action, Loc, Assignee, + ShowFullyQualifiedAssigneeName); } bool Sema::BoundsSafetyCheckInitialization(const InitializedEntity &Entity, const InitializationKind &Kind, AssignmentAction Action, QualType LHSType, Expr *RHSExpr) { - if (!getLangOpts().hasBoundsSafety()) - return true; - - bool ChecksPassed = true; auto SL = Kind.getLocation(); // Note: We don't call `BoundsSafetyCheckAssignmentToCountAttrPtr` here - // because we need conditionalize what is checked. - - // counted_by/counted_by_or_null on incomplete pointee type check. - // - // We skip Variable initializers because we should have already complained - // about those variables in `Sema::BoundsSafetyCheckVarDecl()`. + // because we need conditionalize what is checked. In downstream + // Clang `counted_by` is supported on variable definitions and in that + // implementation an error diagnostic will be emitted on the variable + // definition if the pointee is an incomplete type. To avoid warning about the + // same problem twice (once when the variable is defined, once when Sema + // checks the initializer) we skip checking the initializer if it's a + // variable. if (Action == AssignmentAction::Initializing && Entity.getKind() != InitializedEntity::EK_Variable) { - if (!BoundsSafetyCheckAssignmentToCountAttrPtrWithIncompletePointeeTy( - LHSType, RHSExpr, Action, SL, + if (!CheckAssignmentToCountAttrPtrWithIncompletePointeeTy( + *this, LHSType, RHSExpr, Action, SL, dyn_cast_or_null(Entity.getDecl()), /*ShowFullQualifiedAssigneeName=*/true)) { - - ChecksPassed = false; - - // It's not necessarily bad if this assert fails but we should catch - // if this happens. - assert(Entity.getKind() == InitializedEntity::EK_Member); + return false; } } - return ChecksPassed; + return true; } -static bool BoundsSafetyCheckUseOfCountAttrPtrWithIncompletePointeeTy(Sema &S, - Expr *E) { +bool Sema::BoundsSafetyCheckUseOfCountAttrPtr(const Expr *E) { QualType T = E->getType(); - assert(T->isPointerType()); + if (!T->isPointerType()) + return true; + + NamedDecl *IncompleteTyDecl = nullptr; + auto [CATy, PointeeTy] = + GetCountedByAttrOnIncompletePointee(T, &IncompleteTyDecl); + if (!CATy) + return true; // Generate a string for the diagnostic that describes the "use". // The string is specialized for direct calls to produce a better // diagnostic. - StringRef DirectCallFn; - std::string UseStr; + SmallString<64> UseStr; + bool IsDirectCall = false; if (const auto *CE = dyn_cast(E->IgnoreParens())) { if (const auto *FD = CE->getDirectCallee()) { - DirectCallFn = FD->getName(); + UseStr = FD->getName(); + IsDirectCall = true; } } - int SelectExprKind = DirectCallFn.size() > 0 ? 1 : 0; - if (SelectExprKind) { - UseStr = DirectCallFn; - } else { - llvm::raw_string_ostream SS(UseStr); - E->printPretty(SS, nullptr, PrintingPolicy(S.getPrintingPolicy())); - } - assert(UseStr.size() > 0); - const CountAttributedType *CATy = nullptr; - QualType PointeeTy; - NamedDecl *IncompleteTyDecl = nullptr; - if (!HasCountedByAttrOnIncompletePointee(T, &IncompleteTyDecl, &CATy, - &PointeeTy)) - return true; - assert(CATy && !CATy->isCountInBytes() && !PointeeTy.isNull()); + if (!IsDirectCall) { + llvm::raw_svector_ostream SS(UseStr); + E->printPretty(SS, nullptr, getPrintingPolicy()); + } - S.Diag(E->getBeginLoc(), - diag::err_bounds_safety_counted_by_on_incomplete_type_on_use) - << /*0*/ SelectExprKind << /*1*/ UseStr << /*2*/ T << /*3*/ PointeeTy - << /*4*/ CATy->GetAttributeName(/*WithMacroPrefix=*/true) - << /*5*/ CATy->isOrNull() << E->getSourceRange(); + Diag(E->getBeginLoc(), diag::err_counted_by_on_incomplete_type_on_use) + << IsDirectCall << UseStr << T << PointeeTy + << CATy->getAttributeName(/*WithMacroPrefix=*/true) << CATy->isOrNull() + << E->getSourceRange(); - EmitIncompleteCountedByPointeeNotes(S, CATy, IncompleteTyDecl); + EmitIncompleteCountedByPointeeNotes(*this, CATy, IncompleteTyDecl); return false; } -bool Sema::BoundsSafetyCheckUseOfCountAttrPtr(Expr *E) { - if (!getLangOpts().hasBoundsSafety()) - return true; - - QualType T = E->getType(); - if (!T->isPointerType()) - return true; - - return BoundsSafetyCheckUseOfCountAttrPtrWithIncompletePointeeTy(*this, E); -} - bool Sema::BoundsSafetyCheckResolvedCall(FunctionDecl *FDecl, CallExpr *Call, const FunctionProtoType *ProtoType) { if (!getLangOpts().hasBoundsSafety()) @@ -655,13 +660,11 @@ bool Sema::BoundsSafetyCheckResolvedCall(FunctionDecl *FDecl, CallExpr *Call, static bool BoundsSafetyCheckFunctionParamOrCountAttrWithIncompletePointeeTy( Sema &S, QualType Ty, const ParmVarDecl *ParamDecl) { - const CountAttributedType *CATy = nullptr; - QualType PointeeTy; NamedDecl *IncompleteTyDecl = nullptr; - if (!HasCountedByAttrOnIncompletePointee(Ty, &IncompleteTyDecl, &CATy, - &PointeeTy)) + auto [CATy, PointeeTy] = + GetCountedByAttrOnIncompletePointee(Ty, &IncompleteTyDecl); + if (!CATy) return true; - // Emit Diagnostic StringRef ParamName; if (ParamDecl) @@ -670,13 +673,11 @@ static bool BoundsSafetyCheckFunctionParamOrCountAttrWithIncompletePointeeTy( auto SR = SourceRangeFor(CATy, S); S.Diag(SR.getBegin(), diag::err_bounds_safety_counted_by_on_incomplete_type_on_func_def) - << /*0*/ CATy->GetAttributeName(/*WithMacroPrefix*/ true) + << /*0*/ CATy->getAttributeName(/*WithMacroPrefix*/ true) << /*1*/ (ParamDecl ? 1 : 0) << /*2*/ (ParamName.size() > 0) - << /*3*/ ParamName << /*4*/ Ty << /*5*/ PointeeTy - << /*6*/ CATy->isOrNull() << SR; + << /*3*/ ParamName << /*4*/ Ty << /*5*/ PointeeTy << SR; - EmitIncompleteCountedByPointeeNotes(S, CATy, IncompleteTyDecl, - /*NoteAttrLocation=*/false); + EmitIncompleteCountedByPointeeNotes(S, CATy, IncompleteTyDecl); return false; } @@ -699,24 +700,22 @@ bool Sema::BoundsSafetyCheckReturnTyForFunctionDef(FunctionDecl *FD) { static bool BoundsSafetyCheckVarDeclCountAttrPtrWithIncompletePointeeTy(Sema &S, const VarDecl *VD) { - const CountAttributedType *CATy = nullptr; - QualType PointeeTy; NamedDecl *IncompleteTyDecl = nullptr; - if (!HasCountedByAttrOnIncompletePointee(VD->getType(), &IncompleteTyDecl, - &CATy, &PointeeTy)) + auto [CATy, PointeeTy] = + GetCountedByAttrOnIncompletePointee(VD->getType(), &IncompleteTyDecl); + if (!CATy) return true; SourceRange SR = SourceRangeFor(CATy, S); S.Diag(SR.getBegin(), diag::err_bounds_safety_counted_by_on_incomplete_type_on_var_decl) - << /*0*/ CATy->GetAttributeName(/*WithMacroPrefix=*/true) + << /*0*/ CATy->getAttributeName(/*WithMacroPrefix=*/true) << /*1*/ (VD->isThisDeclarationADefinition() == VarDecl::TentativeDefinition) << /*2*/ VD->getName() << /*3*/ VD->getType() << /*4*/ PointeeTy << /*5*/ CATy->isOrNull() << SR; - EmitIncompleteCountedByPointeeNotes(S, CATy, IncompleteTyDecl, - /*NoteAttrLocation=*/false); + EmitIncompleteCountedByPointeeNotes(S, CATy, IncompleteTyDecl); return false; } @@ -755,12 +754,12 @@ bool Sema::BoundsSafetyCheckCountAttributedTypeHasConstantCountForAssignmentOp( unsigned DiagID = 0; if (IsUnaryOp) { SelectOp = std::get(OpInfo); - DiagID = - diag::warn_bounds_safety_count_attr_pointer_unary_arithmetic_constant_count; + DiagID = diag:: + warn_bounds_safety_count_attr_pointer_unary_arithmetic_constant_count; } else { // Binary operator - DiagID = - diag::warn_bounds_safety_count_attr_pointer_binary_assign_constant_count; + DiagID = diag:: + warn_bounds_safety_count_attr_pointer_binary_assign_constant_count; switch (std::get(OpInfo)) { case BO_AddAssign: // += SelectOp = 1; @@ -783,13 +782,13 @@ bool Sema::BoundsSafetyCheckCountAttributedTypeHasConstantCountForAssignmentOp( // Count is constant Diag(Operand->getExprLoc(), DiagID) << /*0*/ SelectOp << - /*1*/ CATTy->GetAttributeName(/*WithMacroPrefix=*/true) << + /*1*/ CATTy->getAttributeName(/*WithMacroPrefix=*/true) << /*2*/ (CATTy->isCountInBytes() ? 1 : 0) << /*3*/ 0 /* integer constant count*/ << /*4*/ Result.Val.getAsString(getASTContext(), CATTy->getCountExpr()->getType()); Diag(CATTy->getCountExpr()->getExprLoc(), diag::note_named_attribute) - << CATTy->GetAttributeName(/*WithMacroPrefix=*/true); + << CATTy->getAttributeName(/*WithMacroPrefix=*/true); return false; } if (const auto *DRE = @@ -801,18 +800,16 @@ bool Sema::BoundsSafetyCheckCountAttributedTypeHasConstantCountForAssignmentOp( Diag(Operand->getExprLoc(), DiagID) << /*0*/ SelectOp << - /*1*/ CATTy->GetAttributeName(/*WithMacroPrefix=*/true) << + /*1*/ CATTy->getAttributeName(/*WithMacroPrefix=*/true) << /*2*/ (CATTy->isCountInBytes() ? 1 : 0) << /*3*/ 1 /* const qualified declref*/ << /*4*/ VD; Diag(CATTy->getCountExpr()->getExprLoc(), diag::note_named_attribute) - << CATTy->GetAttributeName(/*WithMacroPrefix=*/true); + << CATTy->getAttributeName(/*WithMacroPrefix=*/true); return false; } } - return true; } -/* TO_UPSTREAM(BoundsSafety) OFF*/ } // namespace clang diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index 2fb0f70a6c880..8baff1e4957de 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -6194,8 +6194,8 @@ class ConstructCountAttributedType : // see `HasCountedByAttrOnIncompletePointee()`. This allows the counted_by // attribute to be used on code that prefers to keep its pointees // incomplete until they need to be used. - if (PointeeTy->isIncompletableIncompleteType() || - PointeeTy->isFunctionType() || PointeeTy->isSizelessType() || + if (PointeeTy->isAlwaysIncompleteType() || PointeeTy->isFunctionType() || + PointeeTy->isSizelessType() || PointeeTy->isStructureTypeWithFlexibleArrayMember()) { // Use unspecified pointer attributes for diagnostic purposes. QualType Unsp = S.Context.getBoundsSafetyPointerType( diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index 43bd1d12971d6..0be5dad33624a 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -1086,6 +1086,7 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E, if (!Count.get()) return ExprError(); + // FIXME: Hoist this out of if-else blocks if (!BoundsSafetyCheckUseOfCountAttrPtr(Res.get())) return ExprError(); @@ -1140,6 +1141,9 @@ ExprResult Sema::DefaultLvalueConversion(Expr *E, Res = MaterializeSequenceExpr::Create(Context, Res.get(), OpaqueValues, true); } return Res; + } else { + if (!BoundsSafetyCheckUseOfCountAttrPtr(Res.get())) + return ExprError(); } /* TO_UPSTREAM(BoundsSafety) OFF*/ @@ -16841,7 +16845,7 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, QualType RHSType = CompoundType.isNull() ? RHS.get()->getType() : CompoundType; -/* TO_UPSTREAM(BoundsSafety) ON*/ + /* TO_UPSTREAM(BoundsSafety) ON*/ if (getLangOpts().BoundsSafety) { auto *RecordTy = RHSType->getAs(); if (RecordTy && RecordTy->getDecl()->hasFlexibleArrayMember()) { @@ -16853,8 +16857,9 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, // recovery by continuing as if this worked } } + /* TO_UPSTREAM(BoundsSafety) OFF */ - if (getLangOpts().hasBoundsSafety() && RHS.isUsable()) { + if (RHS.isUsable()) { // Even if this check fails don't return early to allow the best // possible error recovery and to allow any subsequent diagnostics to // work. @@ -16868,11 +16873,10 @@ QualType Sema::CheckAssignmentOperands(Expr *LHSExpr, ExprResult &RHS, ShowFullyQualifiedAssigneeName = true; } - (void)BoundsSafetyCheckAssignmentToCountAttrPtr( + BoundsSafetyCheckAssignmentToCountAttrPtr( LHSType, RHS.get(), AssignmentAction::Assigning, Loc, Assignee, ShowFullyQualifiedAssigneeName); } -/* TO_UPSTREAM(BoundsSafety) OFF */ // OpenCL v1.2 s6.1.1.1 p2: // The half data type can only be used to declare a pointer to a buffer that diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 251d878f3743e..2f9273f09dd9d 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -8610,17 +8610,12 @@ ExprResult InitializationSequence::Perform(Sema &S, Kind.getRange().getEnd()); } else { CurInit = new (S.Context) ImplicitValueInitExpr(Step->Type); - /* TO_UPSTREAM(BoundsSafety) ON*/ - // Note the return value isn't used to return early - // to preserve the AST as best as possible even though an error - // might have occurred. For struct initialization it also allows - // all field assignments to be checked rather than bailing on the - // first error. + // Note the return value isn't used to return a ExprError() when + // initialization fails . For struct initialization allows all field + // assignments to be checked rather than bailing on the first error. S.BoundsSafetyCheckInitialization(Entity, Kind, AssignmentAction::Initializing, - /*LHSType=*/Step->Type, - /*RHSExpr=*/CurInit.get()); - /* TO_UPSTREAM(BoundsSafety) OFF*/ + Step->Type, CurInit.get()); } break; } @@ -8721,6 +8716,13 @@ ExprResult InitializationSequence::Perform(Sema &S, } } + // Note the return value isn't used to return a ExprError() when + // initialization fails. For struct initialization this allows all field + // assignments to be checked rather than bailing on the first error. + S.BoundsSafetyCheckInitialization(Entity, Kind, + getAssignmentAction(Entity, true), + Step->Type, InitialCurInit.get()); + bool Complained; ValueDecl *Assignee = nullptr; /* TO_UPSTREAM(BoundsSafety) ON*/ @@ -8730,18 +8732,6 @@ ExprResult InitializationSequence::Perform(Sema &S, Assignee = Entity.getDecl(); } - // Note the return value isn't used to return early so that additional - // diagnostics can be emitted and to preserve the AST as best as possible - // even though an error might have occurred. For struct initialization it - // also allows all field assignments to be checked rather than bailing on - // the first error. - (void)S.BoundsSafetyCheckInitialization( - Entity, Kind, /*Action=*/getAssignmentAction(Entity, true), - /*LHSType=*/Step->Type, /*RHSExpr=*/InitialCurInit.get()); - - /* TO_UPSTREAM(BoundsSafety) OFF*/ - - /* TO_UPSTREAM(BoundsSafety) ON*/ // Upstream doesn't have `Assignee`. if (S.DiagnoseAssignmentResult(ConvTy, Kind.getLocation(), Step->Type, SourceType, diff --git a/clang/test/BoundsSafety/Sema/counted_by_type_incomplete_completable_enum.c b/clang/test/BoundsSafety/Sema/counted_by_type_incomplete_completable_enum.c index 85d75ebf41a95..b56f461c9eb60 100644 --- a/clang/test/BoundsSafety/Sema/counted_by_type_incomplete_completable_enum.c +++ b/clang/test/BoundsSafety/Sema/counted_by_type_incomplete_completable_enum.c @@ -5,15 +5,15 @@ // Test incomplete enums extern int external_enum_len; -typedef enum incomplete_enum incomplete_enum_t; // expected-note 2{{forward declaration of 'enum incomplete_enum'}} +typedef enum incomplete_enum incomplete_enum_t; // expected-note 2{{consider providing a complete definition for 'enum incomplete_enum'}} extern incomplete_enum_t* __counted_by(external_enum_len) incompleteEnumPtr; // OK extern enum incomplete_enum* __counted_by(external_enum_len) incompleteEnumPtr2; // OK int global_enum_len; // expected-error@+1{{cannot apply '__counted_by' attribute to tentative variable definition 'GlobalCBEnumPtrImplicitInit' with type 'enum incomplete_enum *__single __counted_by(global_enum_len)' (aka 'enum incomplete_enum *__single') because the pointee type 'enum incomplete_enum' is incomplete; consider providing a complete definition for 'enum incomplete_enum' before this definition or using the '__sized_by' attribute}} -enum incomplete_enum* __counted_by(global_enum_len) GlobalCBEnumPtrImplicitInit; +enum incomplete_enum* __counted_by(global_enum_len) GlobalCBEnumPtrImplicitInit; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'GlobalCBONEnumPtrImplicitInit' with type 'enum incomplete_enum *__single __counted_by_or_null(global_enum_len)' (aka 'enum incomplete_enum *__single') because the pointee type 'enum incomplete_enum' is incomplete; consider providing a complete definition for 'enum incomplete_enum' before this definition or using the '__sized_by_or_null' attribute}} -enum incomplete_enum* __counted_by_or_null(global_enum_len) GlobalCBONEnumPtrImplicitInit; +enum incomplete_enum* __counted_by_or_null(global_enum_len) GlobalCBONEnumPtrImplicitInit; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} // Unions are handled like structs for the diagnostics so the testing for structs diff --git a/clang/test/BoundsSafety/Sema/counted_by_type_incomplete_completable_struct.c b/clang/test/BoundsSafety/Sema/counted_by_type_incomplete_completable_struct.c index 66904566d2ad0..4076f36f1f48b 100644 --- a/clang/test/BoundsSafety/Sema/counted_by_type_incomplete_completable_struct.c +++ b/clang/test/BoundsSafety/Sema/counted_by_type_incomplete_completable_struct.c @@ -12,8 +12,8 @@ // the typedef. This seems like the right behavior because the typedef isn't the // forward declaration, `struct IncompleteStructTy` is. // -// expected-note@+1 62{{forward declaration of 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy')}} -struct IncompleteStructTy; // expected-note 153{{forward declaration of 'struct IncompleteStructTy'}} +// expected-note@+1 62{{consider providing a complete definition for 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy')}} +struct IncompleteStructTy; // expected-note 153{{consider providing a complete definition for 'struct IncompleteStructTy'}} typedef struct IncompleteStructTy Incomplete_Struct_t; @@ -29,10 +29,10 @@ void no_consume_ok( // Using the attribute on parameters on a function **definition** is not allowed. void no_consume_ok( - // expected-error@+1{{cannot apply '__counted_by' attribute to parameter 'cb' with type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by' attribute}} - struct IncompleteStructTy* __counted_by(size) cb, - // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to parameter 'cbon' with type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by_or_null' attribute}} - struct IncompleteStructTy* __counted_by_or_null(size) cbon, + // expected-error@+1{{cannot apply '__counted_by' attribute to parameter 'cb' with type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} + struct IncompleteStructTy* __counted_by(size) cb, // expected-note{{consider using '__sized_by' instead of '__counted_by'}} + // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to parameter 'cbon' with type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} + struct IncompleteStructTy* __counted_by_or_null(size) cbon, // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} int size) { } @@ -43,12 +43,12 @@ void no_consume_ok_unnamed_param( int size); // OK void no_consume_ok_unnamed_param( - // expected-error@+2{{cannot apply '__counted_by' attribute to parameter with type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by' attribute}} + // expected-error@+2{{cannot apply '__counted_by' attribute to parameter with type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-warning@+1{{omitting the parameter name in a function definition is a C23 extension}} - struct IncompleteStructTy* __counted_by(size), - // expected-error@+2{{cannot apply '__counted_by_or_null' attribute to parameter with type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by_or_null' attribute}} + struct IncompleteStructTy* __counted_by(size), // expected-note{{consider using '__sized_by' instead of '__counted_by'}} + // expected-error@+2{{cannot apply '__counted_by_or_null' attribute to parameter with type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-warning@+1{{omitting the parameter name in a function definition is a C23 extension}} - struct IncompleteStructTy* __counted_by_or_null(size), + struct IncompleteStructTy* __counted_by_or_null(size), // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} int size) { } @@ -57,10 +57,10 @@ void consume_cb(struct IncompleteStructTy* __counted_by(size_cb), int size_cb); void consume_cbon(struct IncompleteStructTy* __counted_by_or_null(size_cbon), int size_cbon); void consume_param_read_write( - // expected-error@+1{{cannot apply '__counted_by' attribute to parameter 'cb' with type 'struct IncompleteStructTy *__single __counted_by(size_cb)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by' attribute}} - struct IncompleteStructTy* __counted_by(size_cb) cb, - // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to parameter 'cbon' with type 'struct IncompleteStructTy *__single __counted_by_or_null(size_cbon)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by_or_null' attribute}} - struct IncompleteStructTy* __counted_by_or_null(size_cbon) cbon, + // expected-error@+1{{cannot apply '__counted_by' attribute to parameter 'cb' with type 'struct IncompleteStructTy *__single __counted_by(size_cb)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} + struct IncompleteStructTy* __counted_by(size_cb) cb, // expected-note{{consider using '__sized_by' instead of '__counted_by'}} + // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to parameter 'cbon' with type 'struct IncompleteStructTy *__single __counted_by_or_null(size_cbon)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} + struct IncompleteStructTy* __counted_by_or_null(size_cbon) cbon, // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} int size_cb, int size_cbon) { @@ -107,8 +107,8 @@ void no_consume_default_assign( // Attribute on parameters with nested attributes //------------------------------------------------------------------------------ void consume_param_nested( - struct IncompleteStructTy* __counted_by(size1)* cb, // expected-note 3{{__counted_by attribute is here}} - struct IncompleteStructTy* __counted_by_or_null(size2)* cbon, // expected-note 3{{__counted_by_or_null attribute is here}} + struct IncompleteStructTy* __counted_by(size1)* cb, // expected-note 3{{consider using '__sized_by' instead of '__counted_by'}} + struct IncompleteStructTy* __counted_by_or_null(size2)* cbon, // expected-note 3{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} int size1, int size2) { // Surprisingly `&cb[0]` doesn't count as a use. @@ -117,13 +117,13 @@ void consume_param_nested( // expected-error@+1{{pointer with '__counted_by' cannot be pointed to by any other variable; exception is when the variable is passed as a compatible argument to a function}} local = cb; - // expected-error@+1{{cannot assign to object that has type 'struct IncompleteStructTy *__single __counted_by(size1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot assign to object with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(size1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} *cb = 0x0; size1 = 0; - // expected-error@+1{{cannot use 'cb[0]' with type 'struct IncompleteStructTy *__single __counted_by(size1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot use 'cb[0]' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(size1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} void* read_cb = cb[0]; - // expected-error@+1{{cannot use '*cb' with type 'struct IncompleteStructTy *__single __counted_by(size1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot use '*cb' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(size1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} consume_cb(*cb, size1); // expected-error@+1{{not allowed to change out parameter with dependent count}} @@ -134,13 +134,13 @@ void consume_param_nested( // expected-error@+1{{pointer with '__counted_by_or_null' cannot be pointed to by any other variable; exception is when the variable is passed as a compatible argument to a function}} local = cbon; - // expected-error@+1{{cannot assign to object that has type 'struct IncompleteStructTy *__single __counted_by_or_null(size2)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot assign to object with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(size2)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} *cbon = 0x0; size2 = 0; - // expected-error@+1{{cannot use 'cbon[0]' with type 'struct IncompleteStructTy *__single __counted_by_or_null(size2)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot use 'cbon[0]' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(size2)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} void* read_cbon = cbon[0]; - // expected-error@+1{{cannot use '*cbon' with type 'struct IncompleteStructTy *__single __counted_by_or_null(size2)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot use '*cbon' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(size2)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} consume_cbon(*cbon, size2); // expected-error@+1{{not allowed to change out parameter with dependent count}} @@ -151,42 +151,42 @@ void consume_param_nested( // Attribute on return type of called function //------------------------------------------------------------------------------ -// expected-note@+1{{__counted_by attribute is here}} +// expected-note@+1{{consider using '__sized_by' instead of '__counted_by'}} struct IncompleteStructTy* __counted_by(size) ret_cb_IncompleteStructTy(int size); // OK -// expected-note@+1{{__counted_by attribute is here}} +// expected-note@+1{{consider using '__sized_by' instead of '__counted_by'}} Incomplete_Struct_t* __counted_by(size) ret_cb_IncompleteStructTy_typedef(int size); // OK -// expected-note@+1{{__counted_by_or_null attribute is here}} +// expected-note@+1{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} struct IncompleteStructTy* __counted_by_or_null(size) ret_cbon_IncompleteStructTy(int size); // OK -// expected-note@+1{{__counted_by_or_null attribute is here}} +// expected-note@+1{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} Incomplete_Struct_t* __counted_by_or_null(size) ret_cbon_IncompleteStructTy_typedef(int size); // OK -// expected-note@+1{{__counted_by attribute is here}} +// expected-note@+1{{consider using '__sized_by' instead of '__counted_by'}} struct IncompleteStructTy* __counted_by(1) ret_cb_IncompleteStructTy_const_count_one(void); // OK -// expected-note@+1{{__counted_by attribute is here}} +// expected-note@+1{{consider using '__sized_by' instead of '__counted_by'}} Incomplete_Struct_t* __counted_by(1) ret_cb_IncompleteStructTy_typedef_const_count_one(void); // OK -// expected-note@+1{{__counted_by_or_null attribute is here}} +// expected-note@+1{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} struct IncompleteStructTy* __counted_by_or_null(1) ret_cbon_IncompleteStructTy_const_count_one(void); // OK -// expected-note@+1{{__counted_by_or_null attribute is here}} +// expected-note@+1{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} Incomplete_Struct_t* __counted_by_or_null(1) ret_cbon_IncompleteStructTy_typedef_const_count_one(void); // OK void call_fn_returns_incomplete_pointee(void) { int size = 0; - // expected-error@+1{{cannot call 'ret_cb_IncompleteStructTy' with return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot call 'ret_cb_IncompleteStructTy' with '__counted_by' attributed return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} ret_cb_IncompleteStructTy(size); - // expected-error@+1{{cannot call 'ret_cb_IncompleteStructTy_typedef' with return type 'Incomplete_Struct_t *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot call 'ret_cb_IncompleteStructTy_typedef' with '__counted_by' attributed return type 'Incomplete_Struct_t *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} ret_cb_IncompleteStructTy_typedef(size); - // expected-error@+1{{cannot call 'ret_cbon_IncompleteStructTy' with return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot call 'ret_cbon_IncompleteStructTy' with '__counted_by_or_null' attributed return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} ret_cbon_IncompleteStructTy(size); - // expected-error@+1{{cannot call 'ret_cbon_IncompleteStructTy_typedef' with return type 'Incomplete_Struct_t *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot call 'ret_cbon_IncompleteStructTy_typedef' with '__counted_by_or_null' attributed return type 'Incomplete_Struct_t *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} ret_cbon_IncompleteStructTy_typedef(size); - // expected-error@+1{{cannot call 'ret_cb_IncompleteStructTy_const_count_one' with return type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot call 'ret_cb_IncompleteStructTy_const_count_one' with '__counted_by' attributed return type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} ret_cb_IncompleteStructTy_const_count_one(); - // expected-error@+1{{cannot call 'ret_cb_IncompleteStructTy_typedef_const_count_one' with return type 'Incomplete_Struct_t *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot call 'ret_cb_IncompleteStructTy_typedef_const_count_one' with '__counted_by' attributed return type 'Incomplete_Struct_t *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} ret_cb_IncompleteStructTy_typedef_const_count_one(); - // expected-error@+1{{cannot call 'ret_cbon_IncompleteStructTy_const_count_one' with return type 'struct IncompleteStructTy *__single __counted_by_or_null(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot call 'ret_cbon_IncompleteStructTy_const_count_one' with '__counted_by_or_null' attributed return type 'struct IncompleteStructTy *__single __counted_by_or_null(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} ret_cbon_IncompleteStructTy_const_count_one(); - // expected-error@+1{{cannot call 'ret_cbon_IncompleteStructTy_typedef_const_count_one' with return type 'Incomplete_Struct_t *__single __counted_by_or_null(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot call 'ret_cbon_IncompleteStructTy_typedef_const_count_one' with '__counted_by_or_null' attributed return type 'Incomplete_Struct_t *__single __counted_by_or_null(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} ret_cbon_IncompleteStructTy_typedef_const_count_one(); } @@ -194,115 +194,115 @@ void call_fn_returns_incomplete_pointee(void) { // Attribute on return type in function declaration //------------------------------------------------------------------------------ -// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by' attribute}} -struct IncompleteStructTy* __counted_by(size) // expected-note{{__counted_by attribute is here}} +// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by(size) // expected-note 2{{consider using '__sized_by' instead of '__counted_by'}} consume_param_and_return_cb(int size) { - // expected-error@+1{{cannot return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when returning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot return '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} return 0x0; } -// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by' attribute}} -struct IncompleteStructTy* __counted_by(size) +// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by(size) // expected-note{{consider using '__sized_by' instead of '__counted_by'}} consume_param_and_return_cb_missing_return(int size) { // missing return statement } -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by_or_null' attribute}} -struct IncompleteStructTy* __counted_by_or_null(size) +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by_or_null(size) // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} consume_param_and_return_cbon_missing_return(int size) { // missing return statement } -// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by' attribute}} -struct IncompleteStructTy* __counted_by(size) // expected-note 2{{__counted_by attribute is here}} +// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by(size) // expected-note 3{{consider using '__sized_by' instead of '__counted_by'}} consume_param_and_return_cb_multiple_returns(int size) { if (size == 0) - // expected-error@+1{{cannot return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when returning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot return '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} return 0x0; - // expected-error@+1{{cannot return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when returning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot return '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} return 0x0; } -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by_or_null' attribute}} -struct IncompleteStructTy* __counted_by_or_null(size) // expected-note 2{{__counted_by_or_null attribute is here}} +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by_or_null(size) // expected-note 3{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} consume_param_and_return_cbon_multiple_returns(int size) { if (size == 0) - // expected-error@+1{{cannot return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when returning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot return '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} return 0x0; - // expected-error@+1{{cannot return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when returning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot return '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} return 0x0; } -// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by' attribute}} -struct IncompleteStructTy* __counted_by(1) // expected-note{{__counted_by attribute is here}} +// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by(1) // expected-note 2{{consider using '__sized_by' instead of '__counted_by'}} consume_param_and_return_cb_const_count_1(int size) { // rs-error@+2{{returning null from a function with result type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') and count value of 1 always fails}} - // expected-error@+1{{cannot return type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when returning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot return '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} return 0x0; } -// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by' attribute}} -struct IncompleteStructTy* __counted_by(size) // expected-note{{__counted_by attribute is here}} +// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by(size) // expected-note 2{{consider using '__sized_by' instead of '__counted_by'}} consume_param_and_return_cb_single_forge(int size) { // rs-warning@+2{{count value is not statically known: returning 'struct IncompleteStructTy *__single' from a function with result type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') is invalid for any count other than 0 or 1}} - // expected-error@+1{{cannot return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when returning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot return '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} return __unsafe_forge_single(struct IncompleteStructTy*, 0x0); } -// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by' attribute}} -struct IncompleteStructTy* __counted_by(size) // expected-note{{__counted_by attribute is here}} +// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by(size) // expected-note 2{{consider using '__sized_by' instead of '__counted_by'}} consume_param_and_return_cb_single_forge_bidi(int size) { - // expected-error@+1{{cannot return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when returning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot return '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} return __unsafe_forge_bidi_indexable(struct IncompleteStructTy*, 0x0, 4); } -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by_or_null' attribute}} -struct IncompleteStructTy* __counted_by_or_null(size) // expected-note{{__counted_by_or_null attribute is here}} +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by_or_null(size) // expected-note 2{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} consume_param_and_return_cbon(int size) { // TODO: We should consider allowing this because the assignment of nullptr // means the type size isn't needed (rdar://129424354). - // expected-error@+1{{cannot return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when returning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot return '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} return 0x0; } -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by_or_null' attribute}} -struct IncompleteStructTy* __counted_by_or_null(size) // expected-note{{__counted_by_or_null attribute is here}} +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by_or_null(size) // expected-note 2{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} consume_param_and_return_cbon_single_forge(int size) { // rs-warning@+2{{count value is not statically known: returning 'struct IncompleteStructTy *__single' from a function with result type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') is invalid for any count other than 0 or 1 unless the pointer is null}} - // expected-error@+1{{cannot return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when returning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot return '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} return __unsafe_forge_single(struct IncompleteStructTy*, 0x0); } -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by_or_null' attribute}} -struct IncompleteStructTy* __counted_by_or_null(size) // expected-note{{__counted_by_or_null attribute is here}} +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by_or_null(size) // expected-note 2{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} consume_param_and_return_cbon_single_forge_bidi(int size) { - // expected-error@+1{{cannot return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when returning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot return '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} return __unsafe_forge_bidi_indexable(struct IncompleteStructTy*, 0x0, 4); } // Test typedef as the incomplete pointee type -// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'Incomplete_Struct_t *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before the function body or using the '__sized_by' attribute}} -Incomplete_Struct_t* __counted_by(size) // expected-note{{__counted_by attribute is here}} +// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'Incomplete_Struct_t *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} +Incomplete_Struct_t* __counted_by(size) // expected-note 2{{consider using '__sized_by' instead of '__counted_by'}} consume_param_and_return_cb_typedef(int size) { - // expected-error@+1{{cannot return type 'Incomplete_Struct_t *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when returning; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot return '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} return 0x0; } // Check Incomplete type diagnostic and bad conversion diagnostics both emitted on return -// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by' attribute}} -struct IncompleteStructTy* __counted_by(size) // expected-note{{__counted_by attribute is here}} +// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by(size) // expected-note 2{{consider using '__sized_by' instead of '__counted_by'}} consume_param_and_return_cb_bad_conversion(int size) { - // expected-error@+2{{cannot return type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when returning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+2{{cannot return '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{non-pointer to safe pointer conversion is not allowed with -fbounds-safety; use '__unsafe_forge_single' or '__unsafe_forge_bidi_indexable'}} return 0x1; } -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by_or_null' attribut}} -struct IncompleteStructTy* __counted_by_or_null(size) // expected-note{{__counted_by_or_null attribute is here}} +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by_or_null(size) // expected-note 2{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} consume_param_and_return_cbon_bad_conversion(int size) { - // expected-error@+2{{cannot return type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when returning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+2{{cannot return '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{non-pointer to safe pointer conversion is not allowed with -fbounds-safety; use '__unsafe_forge_single' or '__unsafe_forge_bidi_indexable'}} return 0x1; } @@ -310,52 +310,52 @@ struct IncompleteStructTy* __counted_by_or_null(size) // expected-note{{__counte //------------------------------------------------------------------------------ // Pass Arguments to parameters with attribute. //------------------------------------------------------------------------------ -void consume_incomplete_cb(struct IncompleteStructTy* __counted_by(size) c, int size); // expected-note{{__counted_by attribute is here}} -void consume_incomplete_cb_unnamed(struct IncompleteStructTy* __counted_by(size), int size); // expected-note{{__counted_by attribute is here}} -typedef void consume_incomplete_cb_t(struct IncompleteStructTy* __counted_by(size) c, int size); // expected-note{{__counted_by attribute is here}} +void consume_incomplete_cb(struct IncompleteStructTy* __counted_by(size) c, int size); // expected-note{{consider using '__sized_by' instead of '__counted_by'}} +void consume_incomplete_cb_unnamed(struct IncompleteStructTy* __counted_by(size), int size); // expected-note{{consider using '__sized_by' instead of '__counted_by'}} +typedef void consume_incomplete_cb_t(struct IncompleteStructTy* __counted_by(size) c, int size); // expected-note{{consider using '__sized_by' instead of '__counted_by'}} void call_consume_incomplete_cb(consume_incomplete_cb_t indirect_call) { - // expected-error@+1{{cannot pass argument to parameter 'c' that has type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when passing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot pass argument to parameter 'c' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} consume_incomplete_cb(__unsafe_forge_single(struct IncompleteStructTy*, 0x4), 1); - // expected-error@+1{{cannot pass argument to parameter that has type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when passing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot pass argument to parameter with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} consume_incomplete_cb_unnamed(__unsafe_forge_single(struct IncompleteStructTy*, 0x4), 1); - // expected-error@+1{{cannot pass argument to parameter that has type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when passing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot pass argument to parameter with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} indirect_call(__unsafe_forge_single(struct IncompleteStructTy*, 0x4), 1); } -void consume_incomplete_cb_const_count_1(struct IncompleteStructTy* __counted_by(1) c); // expected-note{{__counted_by attribute is here}} -void consume_incomplete_cb_unnamed_const_count_1(struct IncompleteStructTy* __counted_by(1)); // expected-note{{__counted_by attribute is here}} -typedef void consume_incomplete_cb_const_count_1_t(struct IncompleteStructTy* __counted_by(1) c); // expected-note{{__counted_by attribute is here}} +void consume_incomplete_cb_const_count_1(struct IncompleteStructTy* __counted_by(1) c); // expected-note{{consider using '__sized_by' instead of '__counted_by'}} +void consume_incomplete_cb_unnamed_const_count_1(struct IncompleteStructTy* __counted_by(1)); // expected-note{{consider using '__sized_by' instead of '__counted_by'}} +typedef void consume_incomplete_cb_const_count_1_t(struct IncompleteStructTy* __counted_by(1) c); // expected-note{{consider using '__sized_by' instead of '__counted_by'}} void call_consume_incomplete_cb_const_count_1(consume_incomplete_cb_const_count_1_t indirect_call) { - // expected-error@+1{{cannot pass argument to parameter 'c' that has type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when passing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot pass argument to parameter 'c' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} consume_incomplete_cb_const_count_1(__unsafe_forge_single(struct IncompleteStructTy*, 0x4)); - // expected-error@+1{{cannot pass argument to parameter that has type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when passing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot pass argument to parameter with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} consume_incomplete_cb_unnamed_const_count_1(__unsafe_forge_single(struct IncompleteStructTy*, 0x4)); - // expected-error@+1{{cannot pass argument to parameter that has type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when passing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot pass argument to parameter with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} indirect_call(__unsafe_forge_single(struct IncompleteStructTy*, 0x4)); } -void consume_incomplete_cbon(struct IncompleteStructTy* __counted_by_or_null(size) c, int size); // expected-note{{__counted_by_or_null attribute is here}} -void consume_incomplete_cbon_unnamed(struct IncompleteStructTy* __counted_by_or_null(size), int size); // expected-note{{__counted_by_or_null attribute is here}} -typedef void consume_incomplete_cbon_t(struct IncompleteStructTy* __counted_by_or_null(size) c, int size); // expected-note{{__counted_by_or_null attribute is here}} +void consume_incomplete_cbon(struct IncompleteStructTy* __counted_by_or_null(size) c, int size); // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} +void consume_incomplete_cbon_unnamed(struct IncompleteStructTy* __counted_by_or_null(size), int size); // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} +typedef void consume_incomplete_cbon_t(struct IncompleteStructTy* __counted_by_or_null(size) c, int size); // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} void call_consume_incomplete_cbon(consume_incomplete_cbon_t indirect_call) { - // expected-error@+1{{cannot pass argument to parameter 'c' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when passing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot pass argument to parameter 'c' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} consume_incomplete_cbon(__unsafe_forge_single(struct IncompleteStructTy*, 0x4), 1); - // expected-error@+1{{cannot pass argument to parameter that has type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when passing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot pass argument to parameter with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} consume_incomplete_cbon_unnamed(__unsafe_forge_single(struct IncompleteStructTy*, 0x4), 1); - // expected-error@+1{{cannot pass argument to parameter that has type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when passing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot pass argument to parameter with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} indirect_call(__unsafe_forge_single(struct IncompleteStructTy*, 0x4), 1); } -// expected-error@+1{{cannot apply '__counted_by' attribute to parameter 'c' with type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by' attribute}} -void wrap_consume_incomplete_cb(struct IncompleteStructTy* __counted_by(size) c, +// expected-error@+1{{cannot apply '__counted_by' attribute to parameter 'c' with type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} +void wrap_consume_incomplete_cb(struct IncompleteStructTy* __counted_by(size) c, // expected-note{{consider using '__sized_by' instead of '__counted_by'}} int size, consume_incomplete_cb_t indirect_call) { // TODO: We should consider allowing this case. rdar://132031085 // @@ -375,8 +375,8 @@ void wrap_consume_incomplete_cb(struct IncompleteStructTy* __counted_by(size) c, indirect_call(c, size); } -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to parameter 'c' with type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by_or_null' attribute}} -void wrap_consume_incomplete_cbon(struct IncompleteStructTy* __counted_by_or_null(size) c, +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to parameter 'c' with type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} +void wrap_consume_incomplete_cbon(struct IncompleteStructTy* __counted_by_or_null(size) c, // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} int size, consume_incomplete_cbon_t indirect_call) { // TODO: We should consider allowing this case. rdar://132031085 // @@ -473,8 +473,8 @@ struct BuffersCBTyNotUsed { struct BuffersCBTy { int count; int count_typedef; - struct IncompleteStructTy* __counted_by(count) buffer; // expected-note 21{{__counted_by attribute is here}} - Incomplete_Struct_t* __counted_by(count_typedef) buffer_typedef; // expected-note 21{{__counted_by attribute is here}} + struct IncompleteStructTy* __counted_by(count) buffer; // expected-note 21{{consider using '__sized_by' instead of '__counted_by'}} + Incomplete_Struct_t* __counted_by(count_typedef) buffer_typedef; // expected-note 21{{consider using '__sized_by' instead of '__counted_by'}} }; void side_effect(void); @@ -482,33 +482,33 @@ void side_effect(void); void AssignToBuffersCBTy(struct BuffersCBTy* b) { // Check that the diagnostic about missing assignment to the count also shows - // expected-error@+2{{cannot assign to 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+2{{cannot assign to 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{assignment to 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') 'b->buffer' requires corresponding assignment to 'b->count'; add self assignment 'b->count = b->count' if the value has not changed}} b->buffer = 0x0; side_effect(); - // expected-error@+2{{cannot assign to 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@+2{{cannot assign to 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} // expected-error@+1{{assignment to 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') 'b->buffer_typedef' requires corresponding assignment to 'b->count_typedef'; add self assignment 'b->count_typedef = b->count_typedef' if the value has not changed}} b->buffer_typedef = 0x0; // Diagnostic about missing assignment to count should not appear. side_effect(); b->count = 0; - // expected-error@+1{{cannot assign to 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot assign to 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} b->buffer = 0x0; side_effect(); - // expected-error@+1{{cannot assign to 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot assign to 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} b->buffer_typedef = 0x0; b->count_typedef = 0; } struct IncompleteStructTy* ReturnBufferCBTyMember(struct BuffersCBTy* b) { - // expected-error@+1{{cannot use 'b->buffer' with type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot use 'b->buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} return b->buffer; } Incomplete_Struct_t* ReturnBufferCBTyMemberTypeDef(struct BuffersCBTy* b) { - // expected-error@+1{{cannot use 'b->buffer_typedef' with type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot use 'b->buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} return b->buffer_typedef; } @@ -520,39 +520,39 @@ struct BuffersCBONTyNotUsed { struct BuffersCBONTy { int count; int count_typedef; - struct IncompleteStructTy* __counted_by_or_null(count) buffer; // expected-note 21{{__counted_by_or_null attribute is here}} - Incomplete_Struct_t* __counted_by_or_null(count_typedef) buffer_typedef; // expected-note 21{{__counted_by_or_null attribute is here}} + struct IncompleteStructTy* __counted_by_or_null(count) buffer; // expected-note 21{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} + Incomplete_Struct_t* __counted_by_or_null(count_typedef) buffer_typedef; // expected-note 21{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} }; void AssignToBuffersCBONTy(struct BuffersCBONTy* b) { // Check that the diagnostic about missing assignment to the count also shows - // expected-error@+2{{cannot assign to 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+2{{cannot assign to 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{assignment to 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') 'b->buffer' requires corresponding assignment to 'b->count'; add self assignment 'b->count = b->count' if the value has not changed}} b->buffer = 0x0; side_effect(); - // expected-error@+2{{cannot assign to 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@+2{{cannot assign to 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} // expected-error@+1{{assignment to 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') 'b->buffer_typedef' requires corresponding assignment to 'b->count_typedef'; add self assignment 'b->count_typedef = b->count_typedef' if the value has not changed}} b->buffer_typedef = 0x0; // Diagnostic about missing assignment to count should not appear. side_effect(); b->count = 0; - // expected-error@+1{{cannot assign to 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot assign to 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} b->buffer = 0x0; side_effect(); - // expected-error@+1{{cannot assign to 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot assign to 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} b->buffer_typedef = 0x0; b->count_typedef = 0; } struct IncompleteStructTy* ReturnBufferCBONTyMember(struct BuffersCBONTy* b) { - // expected-error@+1{{cannot use 'b->buffer' with type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot use 'b->buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} return b->buffer; } Incomplete_Struct_t* ReturnBufferCBONTyMemberTypeDef(struct BuffersCBONTy* b) { - // expected-error@+1{{cannot use 'b->buffer_typedef' with type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot use 'b->buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} return b->buffer_typedef; } @@ -565,17 +565,17 @@ Incomplete_Struct_t* ReturnBufferCBONTyMemberTypeDef(struct BuffersCBONTy* b) { struct BufferCBNonZeroConstCountTy { int extra_field; - struct IncompleteStructTy* __counted_by(1) ptr; // expected-note 4{{__counted_by attribute is here}} + struct IncompleteStructTy* __counted_by(1) ptr; // expected-note 4{{consider using '__sized_by' instead of '__counted_by'}} }; struct BufferCBNonZeroConstCountFlippedFieldOrderTy { - struct IncompleteStructTy* __counted_by(1) ptr; // expected-note 2{{__counted_by attribute is here}} + struct IncompleteStructTy* __counted_by(1) ptr; // expected-note 2{{consider using '__sized_by' instead of '__counted_by'}} int extra_field; }; struct BufferCBNonZeroDynCountTy { unsigned int count; - struct IncompleteStructTy* __counted_by(count+1) ptr; // expected-note 5{{__counted_by attribute is here}} + struct IncompleteStructTy* __counted_by(count+1) ptr; // expected-note 5{{consider using '__sized_by' instead of '__counted_by'}} }; union BufferCBOrOther { @@ -588,17 +588,17 @@ void InitBuffersCBTy(int size) { struct BuffersCBTy desig_init_0 = { .count = size, .count_typedef = size, - // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} .buffer = 0x0, - // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} .buffer_typedef = 0x0 }; struct BuffersCBTy desig_init_1 = { // .count and .count_typedef not explicitly initialized but are implicitly zero initialized - // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} .buffer = 0x0, - // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} .buffer_typedef = 0x0 }; @@ -607,61 +607,61 @@ void InitBuffersCBTy(int size) { .count_typedef = size, // .buffer and .buffer_typedef are not explicit initialized but are implicitly zero initialized }; - // expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} - // expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + // expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} struct BuffersCBTy implicit_all_zero_init = {0}; // Implicit field init - // expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} - // expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + // expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} // non-designated initializer struct BuffersCBTy non_design_init_0 = { 0, 0, - // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} 0x0, - // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} 0x0 }; struct BuffersCBTy non_design_init_1 = { 0, 0 }; - // expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} - // expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + // expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} struct BuffersCBTy desig_init_invalid_count = { .count = 1, - // expected-error@+2{{cannot initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+2{{cannot initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{initializing 'desig_init_invalid_count.buffer' of type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') and count value of 1 with null always fails}} .buffer = 0x0 }; - // expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} struct BuffersCBTy desig_init_invalid_count_partial = { .count = 1 }; // expected-error@-1{{implicitly initializing 'desig_init_invalid_count_partial.buffer' of type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') and count value of 1 with null always fails}} - // expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} - // expected-error@-3{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + // expected-error@-3{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} struct BuffersCBTy non_desig_init_invalid_count = { 1, 0, - // expected-error@+2{{cannot initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+2{{cannot initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{initializing 'non_desig_init_invalid_count.buffer' of type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') and count value of 1 with null always fails}} 0x0, - // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} 0x0 }; struct BuffersCBTy non_desig_init_invalid_count_partial = {1}; // expected-error@-1{{implicitly initializing 'non_desig_init_invalid_count_partial.buffer' of type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') and count value of 1 with null always fails}} - // expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} - // expected-error@-3{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + // expected-error@-3{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} // Cases where zero-init would create an invalid count struct BufferCBNonZeroConstCountTy design_init_const_count = { - // expected-error@+2{{cannot initialize 'BufferCBNonZeroConstCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+2{{cannot initialize 'BufferCBNonZeroConstCountTy::ptr' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{initializing 'design_init_const_count.ptr' of type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') and count value of 1 with null always fails}} .ptr = 0x0, .extra_field = 0 @@ -672,27 +672,27 @@ void InitBuffersCBTy(int size) { .extra_field = 0x0 }; // expected-error@-1{{implicitly initializing 'design_init_const_count_partial_explicit.ptr' of type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') and count value of 1 with null always fails}} - // expected-error@-2{{cannot implicitly initialize 'BufferCBNonZeroConstCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@-2{{cannot implicitly initialize 'BufferCBNonZeroConstCountTy::ptr' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} struct BufferCBNonZeroConstCountTy implicit_all_zero_init_const_count = {0}; // expected-error@-1{{implicitly initializing 'implicit_all_zero_init_const_count.ptr' of type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') and count value of 1 with null always fails}} - // expected-error@-2{{cannot implicitly initialize 'BufferCBNonZeroConstCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@-2{{cannot implicitly initialize 'BufferCBNonZeroConstCountTy::ptr' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // When the ptr comes first it's seen as an explicit assignment when we write ` = {0}` so we get the incomplete pointee type error diagnostic - // expected-error@+2{{cannot initialize 'BufferCBNonZeroConstCountFlippedFieldOrderTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+2{{cannot initialize 'BufferCBNonZeroConstCountFlippedFieldOrderTy::ptr' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{initializing 'implicit_all_zero_init_const_count_ptr_init.ptr' of type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') and count value of 1 with null always fails}} struct BufferCBNonZeroConstCountFlippedFieldOrderTy implicit_all_zero_init_const_count_ptr_init = {0}; struct BufferCBNonZeroDynCountTy design_init_non_zero_dyn_count = { .count = 0x0, - // expected-error@+2{{cannot initialize 'BufferCBNonZeroDynCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+2{{cannot initialize 'BufferCBNonZeroDynCountTy::ptr' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{initializing 'design_init_non_zero_dyn_count.ptr' of type 'struct IncompleteStructTy *__single __counted_by(count + 1)' (aka 'struct IncompleteStructTy *__single') and count value of 1 with null always fails}} .ptr = 0x0 }; struct BufferCBNonZeroDynCountTy design_init_non_zero_dyn_count_partial_init = { // count is implicitly zero - // expected-error@+2{{cannot initialize 'BufferCBNonZeroDynCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+2{{cannot initialize 'BufferCBNonZeroDynCountTy::ptr' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{initializing 'design_init_non_zero_dyn_count_partial_init.ptr' of type 'struct IncompleteStructTy *__single __counted_by(count + 1)' (aka 'struct IncompleteStructTy *__single') and count value of 1 with null always fails}} .ptr = 0x0 }; @@ -702,15 +702,15 @@ void InitBuffersCBTy(int size) { .count = 0x0 }; // expected-error@-1{{implicitly initializing 'design_init_non_zero_dyn_count_partial_init2.ptr' of type 'struct IncompleteStructTy *__single __counted_by(count + 1)' (aka 'struct IncompleteStructTy *__single') and count value of 1 with null always fails}} - // expected-error@-2{{cannot implicitly initialize 'BufferCBNonZeroDynCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@-2{{cannot implicitly initialize 'BufferCBNonZeroDynCountTy::ptr' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} struct BufferCBNonZeroDynCountTy implicit_all_zero_init_non_zero_dyn_count = {0}; // expected-error@-1{{implicitly initializing 'implicit_all_zero_init_non_zero_dyn_count.ptr' of type 'struct IncompleteStructTy *__single __counted_by(count + 1)' (aka 'struct IncompleteStructTy *__single') and count value of 1 with null always fails}} - // expected-error@-2{{cannot implicitly initialize 'BufferCBNonZeroDynCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@-2{{cannot implicitly initialize 'BufferCBNonZeroDynCountTy::ptr' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} struct BufferCBNonZeroDynCountTy non_desig_init_non_zero_dyn_count = { 0, - // expected-error@+2{{cannot initialize 'BufferCBNonZeroDynCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+2{{cannot initialize 'BufferCBNonZeroDynCountTy::ptr' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{initializing 'non_desig_init_non_zero_dyn_count.ptr' of type 'struct IncompleteStructTy *__single __counted_by(count + 1)' (aka 'struct IncompleteStructTy *__single') and count value of 1 with null always fails}} 0 }; @@ -718,33 +718,33 @@ void InitBuffersCBTy(int size) { // Struct inside a union union BufferCBOrOther UnionDesignInitOther = {.other = 0x0 }; union BufferCBOrOther UnionZeroInit = {0}; - // expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} - // expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + // expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} union BufferCBOrOther UnionDesignInitBufZeroInitStructFields = {.buf = {0}}; - // expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} - // expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + // expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} union BufferCBOrOther UnionDesignInitBufDesignInitStructFields = {.buf = {.count = 0, .buffer = 0x0}}; - // expected-error@-1{{cannot initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} - // expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@-1{{cannot initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + // expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} } struct BuffersCBTy GlobalBuffersCBTy_design_init = { .count = 0, .count_typedef = 0, - // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} .buffer = 0x0, - // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} .buffer_typedef = 0 }; struct BuffersCBTy GlobalBuffersCBTy_non_design_init = { 0, 0, - // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} 0, - // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} 0 }; @@ -753,28 +753,28 @@ struct BuffersCBTy GlobalBuffersCBTy_design_init_partial = { .count_typedef = 0 // buffer and buffer_typedef are implicitly zero initialized }; -// expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} -// expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} +// expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} +// expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} struct BuffersCBTy GlobalBuffersCBTy_non_design_init_partial = { 0, 0, // buffer and buffer_typedef are implicitly zero initialized }; -// expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} -// expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} +// expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} +// expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} struct BuffersCBTy GlobalBuffersCBTy_all_zero_init = {0}; -// expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} -// expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by' attribute}} +// expected-error@-1{{cannot implicitly initialize 'BuffersCBTy::buffer' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} +// expected-error@-2{{cannot implicitly initialize 'BuffersCBTy::buffer_typedef' with '__counted_by' attributed type 'Incomplete_Struct_t *__single __counted_by(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} -// expected-error@+2{{cannot initialize 'BufferCBNonZeroConstCountFlippedFieldOrderTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} +// expected-error@+2{{cannot initialize 'BufferCBNonZeroConstCountFlippedFieldOrderTy::ptr' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{initializing 'GlobalBuffersCBTy_implicit_all_zero_init_const_count_ptr_init.ptr' of type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') and count value of 1 with null always fails}} struct BufferCBNonZeroConstCountFlippedFieldOrderTy GlobalBuffersCBTy_implicit_all_zero_init_const_count_ptr_init = {0}; struct BufferCBNonZeroConstCountTy GlobalBuffersCBTy_const_non_zero_count = { - // expected-error@+2{{cannot initialize 'BufferCBNonZeroConstCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+2{{cannot initialize 'BufferCBNonZeroConstCountTy::ptr' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{initializing 'GlobalBuffersCBTy_const_non_zero_count.ptr' of type 'struct IncompleteStructTy *__single __counted_by(1)' (aka 'struct IncompleteStructTy *__single') and count value of 1 with null always fails}} .ptr = 0x0 }; @@ -789,17 +789,17 @@ union BufferCBONOrOther { struct BufferCBONNonZeroConstCountTy { int extra_field; - struct IncompleteStructTy* __counted_by_or_null(1) ptr; // expected-note 4{{__counted_by_or_null attribute is here}} + struct IncompleteStructTy* __counted_by_or_null(1) ptr; // expected-note 4{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} }; struct BufferCBONNonZeroConstCountFlippedFieldOrderTy { - struct IncompleteStructTy* __counted_by_or_null(1) ptr; // expected-note 2{{__counted_by_or_null attribute is here}} + struct IncompleteStructTy* __counted_by_or_null(1) ptr; // expected-note 2{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} int extra_field; }; struct BufferCBONNonZeroDynCountTy { unsigned int count; - struct IncompleteStructTy* __counted_by_or_null(count+1) ptr; // expected-note 5{{__counted_by_or_null attribute is here}} + struct IncompleteStructTy* __counted_by_or_null(count+1) ptr; // expected-note 5{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} }; void InitBuffersCBONTy(int size) { @@ -808,18 +808,18 @@ void InitBuffersCBONTy(int size) { struct BuffersCBONTy desig_init_0 = { .count = size, .count_typedef = size, - // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} .buffer = 0x0, - // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} .buffer_typedef = 0x0 }; // TODO: Explicit 0x0 initialization should be allowed. rdar://129424354 struct BuffersCBONTy desig_init_1 = { // .count and .count_typedef not explicitly initialized but are implicitly zero initialized - // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} .buffer = 0x0, - // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} .buffer_typedef = 0x0 }; @@ -829,66 +829,66 @@ void InitBuffersCBONTy(int size) { .count_typedef = size, // .buffer and .buffer_typedef are not explicit initialized but are implicitly zero initialized }; - // expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} - // expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + // expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} // TODO: Implicit 0x0 initialization should be allowed. rdar://129424354 struct BuffersCBONTy implicit_all_zero_init = {0}; // Implicit field init - // expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} - // expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + // expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} // non-designated initializer // TODO: Explicit 0x0 initialization should be allowed. rdar://129424354 struct BuffersCBONTy non_design_init_0 = { 0, 0, - // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} 0x0, - // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} 0x0 }; // TODO: Implicit 0x0 initialization should be allowed. rdar://129424354 struct BuffersCBONTy non_design_init_1 = { 0, 0 }; - // expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} - // expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + // expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} // TODO: Explicit and implicit 0x0 initialization should be allowed. rdar://129424354 struct BuffersCBONTy desig_init_invalid_count = { .count = 1, - // expected-error@+2{{cannot initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+2{{cannot initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // .buffer = 0x0 }; - // expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} // TODO: Implicit 0x0 initialization should be allowed. rdar://129424354 struct BuffersCBONTy desig_init_explicit_non_zero_count_partial = { .count = 1 }; - // expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} - // expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + // expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} // TODO: Explicit 0x0 initialization should be allowed. rdar://129424354 struct BuffersCBONTy non_desig_init_invalid_count = { 1, 0, - // expected-error@+2{{cannot initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+2{{cannot initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // 0x0, - // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} 0x0 }; // TODO: Implicit 0x0 initialization should be allowed. rdar://129424354 struct BuffersCBONTy non_desig_init_non_zerocount_partial = {1}; - // expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} - // expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + // expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} // Cases where zero-init would create an invalid count // TODO: Explicit 0x0 initialization should be allowed. rdar://129424354 struct BufferCBONNonZeroConstCountTy design_init_const_count = { - // expected-error@+2{{cannot initialize 'BufferCBONNonZeroConstCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+2{{cannot initialize 'BufferCBONNonZeroConstCountTy::ptr' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // .ptr = 0x0, .extra_field = 0 @@ -899,22 +899,22 @@ void InitBuffersCBONTy(int size) { // .ptr is implicitly zero initialized .extra_field = 0x0 }; - // expected-error@-1{{cannot implicitly initialize 'BufferCBONNonZeroConstCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BufferCBONNonZeroConstCountTy::ptr' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // TODO: Implicit 0x0 initialization should be allowed. rdar://129424354 struct BufferCBONNonZeroConstCountTy implicit_all_zero_init_const_count = {0}; - // expected-error@-1{{cannot implicitly initialize 'BufferCBONNonZeroConstCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BufferCBONNonZeroConstCountTy::ptr' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // TODO: Explicit 0x0 initialization should be allowed. rdar://129424354 // When the ptr comes first it's seen as an explicit assignment when we write ` = {0}` so we get the incomplete pointee type error diagnostic - // expected-error@+2{{cannot initialize 'BufferCBONNonZeroConstCountFlippedFieldOrderTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+2{{cannot initialize 'BufferCBONNonZeroConstCountFlippedFieldOrderTy::ptr' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // struct BufferCBONNonZeroConstCountFlippedFieldOrderTy implicit_all_zero_init_const_count_ptr_init = {0}; // TODO: Explicit 0x0 initialization should be allowed. rdar://129424354 struct BufferCBONNonZeroDynCountTy design_init_non_zero_dyn_count = { .count = 0x0, - // expected-error@+2{{cannot initialize 'BufferCBONNonZeroDynCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+2{{cannot initialize 'BufferCBONNonZeroDynCountTy::ptr' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // .ptr = 0x0 }; @@ -922,7 +922,7 @@ void InitBuffersCBONTy(int size) { // TODO: Explicit 0x0 initialization should be allowed. rdar://129424354 struct BufferCBONNonZeroDynCountTy design_init_non_zero_dyn_count_partial_init = { // count is implicitly zero - // expected-error@+2{{cannot initialize 'BufferCBONNonZeroDynCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+2{{cannot initialize 'BufferCBONNonZeroDynCountTy::ptr' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // .ptr = 0x0 }; @@ -932,16 +932,16 @@ void InitBuffersCBONTy(int size) { // ptr is implicitly zero initialized .count = 0x0 }; - // expected-error@-1{{cannot implicitly initialize 'BufferCBONNonZeroDynCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BufferCBONNonZeroDynCountTy::ptr' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // TODO: Implicit 0x0 initialization should be allowed. rdar://129424354 struct BufferCBONNonZeroDynCountTy implicit_all_zero_init_non_zero_dyn_count = {0}; - // expected-error@-1{{cannot implicitly initialize 'BufferCBONNonZeroDynCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BufferCBONNonZeroDynCountTy::ptr' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // TODO: Explicit 0x0 initialization should be allowed. rdar://129424354 struct BufferCBONNonZeroDynCountTy non_desig_init_non_zero_dyn_count = { 0, - // expected-error@+2{{cannot initialize 'BufferCBONNonZeroDynCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+2{{cannot initialize 'BufferCBONNonZeroDynCountTy::ptr' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count + 1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // 0 }; @@ -949,16 +949,16 @@ void InitBuffersCBONTy(int size) { // Struct inside a union union BufferCBONOrOther UnionDesignInitOther = {.other = 0x0 }; union BufferCBONOrOther UnionZeroInit = {0}; - // expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} - // expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + // expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} union BufferCBONOrOther UnionDesignInitBufZeroInitStructFields = {.buf = {0}}; - // expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} - // expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + // expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} union BufferCBONOrOther UnionDesignInitBufDesignInitStructFields = {.buf = {.count = 0, .buffer = 0x0}}; - // expected-error@-1{{cannot initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} - // expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@-1{{cannot initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + // expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} } // XXX @@ -966,18 +966,18 @@ void InitBuffersCBONTy(int size) { struct BuffersCBONTy GlobalBuffersCBONTy_design_init = { .count = 0, .count_typedef = 0, - // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} .buffer = 0x0, - // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} .buffer_typedef = 0 }; struct BuffersCBONTy GlobalBuffersCBONTy_non_design_init = { 0, 0, - // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} 0, - // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} 0 }; @@ -986,28 +986,28 @@ struct BuffersCBONTy GlobalBuffersCBONTy_design_init_partial = { .count_typedef = 0 // buffer and buffer_typedef are implicitly zero initialized }; -// expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} -// expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} +// expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} +// expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} struct BuffersCBONTy GlobalBuffersCBONTy_non_design_init_partial = { 0, 0, // buffer and buffer_typedef are implicitly zero initialized }; -// expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} -// expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} +// expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} +// expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} struct BuffersCBONTy GlobalBuffersCBONTy_all_zero_init = {0}; -// expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} -// expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' that has type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'Incomplete_Struct_t' or using the '__sized_by_or_null' attribute}} +// expected-error@-1{{cannot implicitly initialize 'BuffersCBONTy::buffer' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} +// expected-error@-2{{cannot implicitly initialize 'BuffersCBONTy::buffer_typedef' with '__counted_by_or_null' attributed type 'Incomplete_Struct_t *__single __counted_by_or_null(count_typedef)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} -// expected-error@+2{{cannot initialize 'BufferCBONNonZeroConstCountFlippedFieldOrderTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} +// expected-error@+2{{cannot initialize 'BufferCBONNonZeroConstCountFlippedFieldOrderTy::ptr' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // struct BufferCBONNonZeroConstCountFlippedFieldOrderTy GlobalBuffersCBONTy_implicit_all_zero_init_const_count_ptr_init = {0}; struct BufferCBONNonZeroConstCountTy GlobalBuffersCBONTy_const_non_zero_count = { - // expected-error@+2{{cannot initialize 'BufferCBONNonZeroConstCountTy::ptr' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+2{{cannot initialize 'BufferCBONNonZeroConstCountTy::ptr' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(1)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // .ptr = 0x0 }; @@ -1018,65 +1018,65 @@ struct BufferCBONNonZeroConstCountTy GlobalBuffersCBONTy_const_non_zero_count = void local_cb_init_and_assign(int s) { int size = s; - // expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'local_init' with type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} - struct IncompleteStructTy* __counted_by(size) local_init = 0x0; + // expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'local_init' with type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + struct IncompleteStructTy* __counted_by(size) local_init = 0x0; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} local_init = 0x0; int implicit_size = s; - // expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'implicit_init' with type 'struct IncompleteStructTy *__single __counted_by(implicit_size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} - struct IncompleteStructTy* __counted_by(implicit_size) implicit_init; + // expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'implicit_init' with type 'struct IncompleteStructTy *__single __counted_by(implicit_size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + struct IncompleteStructTy* __counted_by(implicit_size) implicit_init; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} implicit_init = 0x0; } void local_cb_init_and_assign_constant_count(void) { // Check we also emit diagnostics about assigning nullptr to `__counted_by(X)` where X > 0 // - // expected-error@+2{{cannot apply '__counted_by' attribute to variable definition 'local_init' with type 'struct IncompleteStructTy *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} + // expected-error@+2{{cannot apply '__counted_by' attribute to variable definition 'local_init' with type 'struct IncompleteStructTy *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{initializing 'local_init' of type 'struct IncompleteStructTy *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') and count value of 5 with null always fails}} - struct IncompleteStructTy* __counted_by(5) local_init = 0x0; + struct IncompleteStructTy* __counted_by(5) local_init = 0x0; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} local_init = 0x0; // Diagnostic suppressed because the VarDecl is invalid // There should be no diagnostic about assigning nullptr // TODO: We should consider allowing this given that the type size isn't // really needed when the count is 0 (rdar://129424147). - // expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'local_init_zero' with type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} - struct IncompleteStructTy* __counted_by(0) local_init_zero = 0x0; + // expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'local_init_zero' with type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + struct IncompleteStructTy* __counted_by(0) local_init_zero = 0x0; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} local_init_zero = 0x0; // Diagnostic suppressed because the VarDecl is invalid - // expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'local_init2' with type 'struct IncompleteStructTy *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} - struct IncompleteStructTy* __counted_by(5) local_init2 = __unsafe_forge_bidi_indexable(struct IncompleteStructTy*, 0x4, 4); + // expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'local_init2' with type 'struct IncompleteStructTy *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + struct IncompleteStructTy* __counted_by(5) local_init2 = __unsafe_forge_bidi_indexable(struct IncompleteStructTy*, 0x4, 4); // expected-note{{consider using '__sized_by' instead of '__counted_by'}} local_init2 = __unsafe_forge_bidi_indexable(struct IncompleteStructTy*, 0x4, 4); // Diagnostic suppressed because the VarDecl is invalid } void local_cbon_init_and_assign(int s) { int size = s; - // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'local_init' with type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} - struct IncompleteStructTy* __counted_by_or_null(size) local_init = 0x0; + // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'local_init' with type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + struct IncompleteStructTy* __counted_by_or_null(size) local_init = 0x0; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} local_init = 0x0; int implicit_size = s; - // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'implicit_init' with type 'struct IncompleteStructTy *__single __counted_by_or_null(implicit_size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} - struct IncompleteStructTy* __counted_by_or_null(implicit_size) implicit_init; + // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'implicit_init' with type 'struct IncompleteStructTy *__single __counted_by_or_null(implicit_size)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + struct IncompleteStructTy* __counted_by_or_null(implicit_size) implicit_init; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} implicit_init = 0x0; } void local_cbon_init_and_assign_constant_count(void) { // TODO: We should consider allowing this because the assignment of nullptr // means the type size isn't needed (rdar://129424354). - // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'local_init' with type 'struct IncompleteStructTy *__single __counted_by_or_null(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} - struct IncompleteStructTy* __counted_by_or_null(5) local_init = 0x0; + // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'local_init' with type 'struct IncompleteStructTy *__single __counted_by_or_null(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + struct IncompleteStructTy* __counted_by_or_null(5) local_init = 0x0; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} local_init = 0x0; // Diagnostic suppressed because the VarDecl is invalid // There should be no diagnostic about assigning nullptr // TODO: We should consider allowing this given that the type size isn't // really needed when the count is 0 (rdar://129424147). - // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'local_init_zero' with type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} - struct IncompleteStructTy* __counted_by_or_null(0) local_init_zero = 0x0; + // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'local_init_zero' with type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + struct IncompleteStructTy* __counted_by_or_null(0) local_init_zero = 0x0; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} local_init_zero = 0x0; // Diagnostic suppressed because the VarDecl is invalid - // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'local_init2' with type 'struct IncompleteStructTy *__single __counted_by_or_null(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} - struct IncompleteStructTy* __counted_by_or_null(5) local_init2 = __unsafe_forge_bidi_indexable(struct IncompleteStructTy*, 0x4, 4); + // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'local_init2' with type 'struct IncompleteStructTy *__single __counted_by_or_null(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} + struct IncompleteStructTy* __counted_by_or_null(5) local_init2 = __unsafe_forge_bidi_indexable(struct IncompleteStructTy*, 0x4, 4); // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} local_init2 = __unsafe_forge_bidi_indexable(struct IncompleteStructTy*, 0x4, 4); // Diagnostic suppressed because the VarDecl is invalid } @@ -1086,41 +1086,41 @@ void local_cbon_init_and_assign_constant_count(void) { // NOTE: Tentative definitions are mostly tested in `counted_by_type_incomplete_completable_struct_tentative_defs.c`. extern int external_count; -// expected-note@+1 3{{__counted_by attribute is here}} +// expected-note@+1 3{{consider using '__sized_by' instead of '__counted_by'}} extern struct IncompleteStructTy* __counted_by(external_count) GlobalCBPtrToIncompleteTy; // OK extern Incomplete_Struct_t* __counted_by(external_count) GlobalCBPtrToIncompleteTyTypeDef; // OK void use_GlobalCBPtrToIncompleteTy(void) { - // expected-error@+2{{cannot assign to 'GlobalCBPtrToIncompleteTy' that has type 'struct IncompleteStructTy *__single __counted_by(external_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+2{{cannot assign to 'GlobalCBPtrToIncompleteTy' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(external_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{assignment to 'struct IncompleteStructTy *__single __counted_by(external_count)' (aka 'struct IncompleteStructTy *__single') 'GlobalCBPtrToIncompleteTy' requires corresponding assignment to 'external_count'; add self assignment 'external_count = external_count' if the value has not changed}} GlobalCBPtrToIncompleteTy = 0x0; - // expected-error@+1{{cannot use 'GlobalCBPtrToIncompleteTy' with type 'struct IncompleteStructTy *__single __counted_by(external_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot use 'GlobalCBPtrToIncompleteTy' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(external_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} GlobalCBPtrToIncompleteTy[0] = 0; - // expected-error@+1{{cannot use 'GlobalCBPtrToIncompleteTy' with type 'struct IncompleteStructTy *__single __counted_by(external_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot use 'GlobalCBPtrToIncompleteTy' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(external_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} consume_incomplete_cb(GlobalCBPtrToIncompleteTy, external_count); } static int global_count; -// expected-error@+1{{cannot apply '__counted_by' attribute to tentative variable definition 'GlobalCBPtrImplicitInit' with type 'struct IncompleteStructTy *__single __counted_by(global_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} -static struct IncompleteStructTy* __counted_by(global_count) GlobalCBPtrImplicitInit; // expected-note 3{{__counted_by attribute is here}} -// expected-error@+1{{cannot apply '__counted_by' attribute to tentative variable definition 'GlobalCBPtrImplicitInitTypeDef' with type 'Incomplete_Struct_t *__single __counted_by(global_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before this definition or using the '__sized_by' attribute}} -static Incomplete_Struct_t* __counted_by(global_count) GlobalCBPtrImplicitInitTypeDef; +// expected-error@+1{{cannot apply '__counted_by' attribute to tentative variable definition 'GlobalCBPtrImplicitInit' with type 'struct IncompleteStructTy *__single __counted_by(global_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} +static struct IncompleteStructTy* __counted_by(global_count) GlobalCBPtrImplicitInit; // expected-note 4{{consider using '__sized_by' instead of '__counted_by'}} +// expected-error@+1{{cannot apply '__counted_by' attribute to tentative variable definition 'GlobalCBPtrImplicitInitTypeDef' with type 'Incomplete_Struct_t *__single __counted_by(global_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} +static Incomplete_Struct_t* __counted_by(global_count) GlobalCBPtrImplicitInitTypeDef; // expected-note {{consider using '__sized_by' instead of '__counted_by'}} void use_GlobalCBPtrImplicitInit(void) { - // expected-error@+2{{cannot assign to 'GlobalCBPtrImplicitInit' that has type 'struct IncompleteStructTy *__single __counted_by(global_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+2{{cannot assign to 'GlobalCBPtrImplicitInit' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(global_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{assignment to 'struct IncompleteStructTy *__single __counted_by(global_count)' (aka 'struct IncompleteStructTy *__single') 'GlobalCBPtrImplicitInit' requires corresponding assignment to 'global_count'; add self assignment 'global_count = global_count' if the value has not changed}} GlobalCBPtrImplicitInit = 0x0; - // expected-error@+1{{cannot use 'GlobalCBPtrImplicitInit' with type 'struct IncompleteStructTy *__single __counted_by(global_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot use 'GlobalCBPtrImplicitInit' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(global_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} GlobalCBPtrImplicitInit[0] = 0; - // expected-error@+1{{cannot use 'GlobalCBPtrImplicitInit' with type 'struct IncompleteStructTy *__single __counted_by(global_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot use 'GlobalCBPtrImplicitInit' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(global_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} consume_incomplete_cb(GlobalCBPtrImplicitInit, global_count); } int global_count_non_static = 0; -// expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExplicitInit' with type 'struct IncompleteStructTy *__single __counted_by(global_count_non_static)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} -struct IncompleteStructTy* __counted_by(global_count_non_static) GlobalCBPtrExplicitInit = 0x0; -// expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExplicitInitTypeDef' with type 'Incomplete_Struct_t *__single __counted_by(global_count_non_static)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before this definition or using the '__sized_by' attribute}} -Incomplete_Struct_t* __counted_by(global_count_non_static) GlobalCBPtrExplicitInitTypeDef = 0x0; +// expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExplicitInit' with type 'struct IncompleteStructTy *__single __counted_by(global_count_non_static)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by(global_count_non_static) GlobalCBPtrExplicitInit = 0x0; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} +// expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExplicitInitTypeDef' with type 'Incomplete_Struct_t *__single __counted_by(global_count_non_static)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} +Incomplete_Struct_t* __counted_by(global_count_non_static) GlobalCBPtrExplicitInitTypeDef = 0x0; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} void use_GlobalCBPtrExplicitInit(void) { // No diagnostics because the VarDecl is marked as invalid at this point @@ -1132,36 +1132,36 @@ void use_GlobalCBPtrExplicitInit(void) { // This is very unidiomatic C but it seems to be legal. // expected-warning@+1{{'extern' variable has an initializer}} extern int global_count_extern = 0; -// expected-error@+2{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExplicitInitExtern' with type 'struct IncompleteStructTy *__single __counted_by(global_count_extern)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribut}} +// expected-error@+2{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExplicitInitExtern' with type 'struct IncompleteStructTy *__single __counted_by(global_count_extern)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-warning@+1 2{{'extern' variable has an initializer}} TODO: This shouldn't be emitted twice. rdar://133001618 -extern struct IncompleteStructTy* __counted_by(global_count_extern) GlobalCBPtrExplicitInitExtern = 0x0; -// expected-error@+2{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExplicitInitTypeDefExtern' with type 'Incomplete_Struct_t *__single __counted_by(global_count_extern)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before this definition or using the '__sized_by' attribute}} +extern struct IncompleteStructTy* __counted_by(global_count_extern) GlobalCBPtrExplicitInitExtern = 0x0; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} +// expected-error@+2{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExplicitInitTypeDefExtern' with type 'Incomplete_Struct_t *__single __counted_by(global_count_extern)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} // expected-warning@+1 2{{'extern' variable has an initializer}} TODO: This shouldn't be emitted twice. rdar://133001618 -extern Incomplete_Struct_t* __counted_by(global_count_extern) GlobalCBPtrExplicitInitTypeDefExtern = 0x0; +extern Incomplete_Struct_t* __counted_by(global_count_extern) GlobalCBPtrExplicitInitTypeDefExtern = 0x0; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} // TODO: We should consider allowing this given that the pointee type size isn't // really needed when the count is 0 (rdar://129424147) -// expected-error@+1{{cannot apply '__counted_by' attribute to tentative variable definition 'GlobalCBPtrImplicitInitConstantZeroCount' with type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} -struct IncompleteStructTy* __counted_by(0) GlobalCBPtrImplicitInitConstantZeroCount; -// expected-error@+1{{cannot apply '__counted_by' attribute to tentative variable definition 'GlobalCBPtrImplicitInitConstantZeroCountTypeDef' with type 'Incomplete_Struct_t *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before this definition or using the '__sized_by' attribute}} -Incomplete_Struct_t* __counted_by(0) GlobalCBPtrImplicitInitConstantZeroCountTypeDef; -// expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExplicitInitConstantZeroCount' with type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} -struct IncompleteStructTy* __counted_by(0) GlobalCBPtrExplicitInitConstantZeroCount = 0x0; -// expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExplicitInitConstantZeroCountTypeDef' with type 'Incomplete_Struct_t *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before this definition or using the '__sized_by' attribute}} -Incomplete_Struct_t* __counted_by(0) GlobalCBPtrExplicitInitConstantZeroCountTypeDef = 0x0; - -// expected-error@+2{{cannot apply '__counted_by' attribute to tentative variable definition 'GlobalCBPtrImplicitInitConstantNonZeroCount' with type 'struct IncompleteStructTy *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} +// expected-error@+1{{cannot apply '__counted_by' attribute to tentative variable definition 'GlobalCBPtrImplicitInitConstantZeroCount' with type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by(0) GlobalCBPtrImplicitInitConstantZeroCount; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} +// expected-error@+1{{cannot apply '__counted_by' attribute to tentative variable definition 'GlobalCBPtrImplicitInitConstantZeroCountTypeDef' with type 'Incomplete_Struct_t *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} +Incomplete_Struct_t* __counted_by(0) GlobalCBPtrImplicitInitConstantZeroCountTypeDef; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} +// expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExplicitInitConstantZeroCount' with type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by(0) GlobalCBPtrExplicitInitConstantZeroCount = 0x0; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} +// expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExplicitInitConstantZeroCountTypeDef' with type 'Incomplete_Struct_t *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} +Incomplete_Struct_t* __counted_by(0) GlobalCBPtrExplicitInitConstantZeroCountTypeDef = 0x0; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} + +// expected-error@+2{{cannot apply '__counted_by' attribute to tentative variable definition 'GlobalCBPtrImplicitInitConstantNonZeroCount' with type 'struct IncompleteStructTy *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{implicitly initializing 'GlobalCBPtrImplicitInitConstantNonZeroCount' of type 'struct IncompleteStructTy *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') and count value of 5 with null always fails}} -struct IncompleteStructTy* __counted_by(5) GlobalCBPtrImplicitInitConstantNonZeroCount; -// expected-error@+2{{cannot apply '__counted_by' attribute to tentative variable definition 'GlobalCBPtrImplicitInitConstantNonZeroCountTypeDef' with type 'Incomplete_Struct_t *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before this definition or using the '__sized_by' attribute}} +struct IncompleteStructTy* __counted_by(5) GlobalCBPtrImplicitInitConstantNonZeroCount; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} +// expected-error@+2{{cannot apply '__counted_by' attribute to tentative variable definition 'GlobalCBPtrImplicitInitConstantNonZeroCountTypeDef' with type 'Incomplete_Struct_t *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} // expected-error@+1{{implicitly initializing 'GlobalCBPtrImplicitInitConstantNonZeroCountTypeDef' of type 'Incomplete_Struct_t *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') and count value of 5 with null always fails}} -Incomplete_Struct_t* __counted_by(5) GlobalCBPtrImplicitInitConstantNonZeroCountTypeDef; -// expected-error@+2{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExplicitInitConstantNonZeroCount' with type 'struct IncompleteStructTy *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} +Incomplete_Struct_t* __counted_by(5) GlobalCBPtrImplicitInitConstantNonZeroCountTypeDef; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} +// expected-error@+2{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExplicitInitConstantNonZeroCount' with type 'struct IncompleteStructTy *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{initializing 'GlobalCBPtrExplicitInitConstantNonZeroCount' of type 'struct IncompleteStructTy *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') and count value of 5 with null always fails}} -struct IncompleteStructTy* __counted_by(5) GlobalCBPtrExplicitInitConstantNonZeroCount = 0x0; -// expected-error@+2{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExplicitInitConstantNonZeroCountTypeDef' with type 'Incomplete_Struct_t *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before this definition or using the '__sized_by' attribute}} +struct IncompleteStructTy* __counted_by(5) GlobalCBPtrExplicitInitConstantNonZeroCount = 0x0; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} +// expected-error@+2{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExplicitInitConstantNonZeroCountTypeDef' with type 'Incomplete_Struct_t *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} // expected-error@+1{{initializing 'GlobalCBPtrExplicitInitConstantNonZeroCountTypeDef' of type 'Incomplete_Struct_t *__single __counted_by(5)' (aka 'struct IncompleteStructTy *__single') and count value of 5 with null always fails}} -Incomplete_Struct_t* __counted_by(5) GlobalCBPtrExplicitInitConstantNonZeroCountTypeDef = 0x0; +Incomplete_Struct_t* __counted_by(5) GlobalCBPtrExplicitInitConstantNonZeroCountTypeDef = 0x0; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} //------------------------------------------------------------------------------ // Global __counted_by_or_null variables @@ -1170,47 +1170,47 @@ Incomplete_Struct_t* __counted_by(5) GlobalCBPtrExplicitInitConstantNonZeroCount extern int external_count_cbon; extern int external_count_cbon_typedef; -// expected-note@+1 3{{__counted_by_or_null attribute is here}} +// expected-note@+1 3{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} extern struct IncompleteStructTy* __counted_by_or_null(external_count_cbon) GlobalCBONPtrToIncompleteTy; // OK extern Incomplete_Struct_t* __counted_by_or_null(external_count_cbon_typedef) GlobalCBONPtrToIncompleteTyTypeDef; // OK void use_GlobalCBONPtrToIncompleteTy(void) { - // expected-error@+2{{cannot assign to 'GlobalCBONPtrToIncompleteTy' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(external_count_cbon)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+2{{cannot assign to 'GlobalCBONPtrToIncompleteTy' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(external_count_cbon)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{assignment to 'struct IncompleteStructTy *__single __counted_by_or_null(external_count_cbon)' (aka 'struct IncompleteStructTy *__single') 'GlobalCBONPtrToIncompleteTy' requires corresponding assignment to 'external_count_cbon'; add self assignment 'external_count_cbon = external_count_cbon' if the value has not changed}} GlobalCBONPtrToIncompleteTy = 0x0; - // expected-error@+1{{cannot use 'GlobalCBONPtrToIncompleteTy' with type 'struct IncompleteStructTy *__single __counted_by_or_null(external_count_cbon)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot use 'GlobalCBONPtrToIncompleteTy' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(external_count_cbon)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} GlobalCBONPtrToIncompleteTy[0] = 0; - // expected-error@+1{{cannot use 'GlobalCBONPtrToIncompleteTy' with type 'struct IncompleteStructTy *__single __counted_by_or_null(external_count_cbon)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot use 'GlobalCBONPtrToIncompleteTy' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(external_count_cbon)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} consume_incomplete_cbon(GlobalCBONPtrToIncompleteTy, external_count); } static int global_count_cbon; -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'GlobalCBONPtrImplicitInit' with type 'struct IncompleteStructTy *__single __counted_by_or_null(global_count_cbon)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} -static struct IncompleteStructTy* __counted_by_or_null(global_count_cbon) GlobalCBONPtrImplicitInit; // expected-note 3{{__counted_by_or_null attribute is here}} -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'GlobalCBONPtrImplicitInitTypeDef' with type 'Incomplete_Struct_t *__single __counted_by_or_null(global_count_cbon)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before this definition or using the '__sized_by_or_null' attribute}} -static Incomplete_Struct_t* __counted_by_or_null(global_count_cbon) GlobalCBONPtrImplicitInitTypeDef; +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'GlobalCBONPtrImplicitInit' with type 'struct IncompleteStructTy *__single __counted_by_or_null(global_count_cbon)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} +static struct IncompleteStructTy* __counted_by_or_null(global_count_cbon) GlobalCBONPtrImplicitInit; // expected-note 4{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'GlobalCBONPtrImplicitInitTypeDef' with type 'Incomplete_Struct_t *__single __counted_by_or_null(global_count_cbon)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} +static Incomplete_Struct_t* __counted_by_or_null(global_count_cbon) GlobalCBONPtrImplicitInitTypeDef; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} void use_GlobalCBONPtrImplicitInit(void) { - // expected-error@+2{{cannot assign to 'GlobalCBONPtrImplicitInit' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(global_count_cbon)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+2{{cannot assign to 'GlobalCBONPtrImplicitInit' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(global_count_cbon)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-error@+1{{assignment to 'struct IncompleteStructTy *__single __counted_by_or_null(global_count_cbon)' (aka 'struct IncompleteStructTy *__single') 'GlobalCBONPtrImplicitInit' requires corresponding assignment to 'global_count_cbon'; add self assignment 'global_count_cbon = global_count_cbon' if the value has not changed}} GlobalCBONPtrImplicitInit = 0x0; - // expected-error@+1{{cannot use 'GlobalCBONPtrImplicitInit' with type 'struct IncompleteStructTy *__single __counted_by_or_null(global_count_cbon)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot use 'GlobalCBONPtrImplicitInit' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(global_count_cbon)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} GlobalCBONPtrImplicitInit[0] = 0; - // expected-error@+1{{cannot use 'GlobalCBONPtrImplicitInit' with type 'struct IncompleteStructTy *__single __counted_by_or_null(global_count_cbon)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot use 'GlobalCBONPtrImplicitInit' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(global_count_cbon)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} consume_incomplete_cbon(GlobalCBONPtrImplicitInit, global_count_cbon); } int global_count_cbon_non_static = 0; -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExplicitInit' with type 'struct IncompleteStructTy *__single __counted_by_or_null(global_count_cbon_non_static)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} -struct IncompleteStructTy* __counted_by_or_null(global_count_cbon_non_static) GlobalCBONPtrExplicitInit = 0x0; -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExplicitInitTypeDef' with type 'Incomplete_Struct_t *__single __counted_by_or_null(global_count_cbon_non_static)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before this definition or using the '__sized_by_or_null' attribute}} -Incomplete_Struct_t* __counted_by_or_null(global_count_cbon_non_static) GlobalCBONPtrExplicitInitTypeDef = 0x0; +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExplicitInit' with type 'struct IncompleteStructTy *__single __counted_by_or_null(global_count_cbon_non_static)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by_or_null(global_count_cbon_non_static) GlobalCBONPtrExplicitInit = 0x0; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExplicitInitTypeDef' with type 'Incomplete_Struct_t *__single __counted_by_or_null(global_count_cbon_non_static)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} +Incomplete_Struct_t* __counted_by_or_null(global_count_cbon_non_static) GlobalCBONPtrExplicitInitTypeDef = 0x0; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} void use_GlobalCBONPtrExplicitInit(void) { // No diagnostics because the VarDecl is marked as invalid at this point @@ -1224,51 +1224,51 @@ void use_GlobalCBONPtrExplicitInit(void) { // This is very unidiomatic C but it seems to be legal. // expected-warning@+1{{'extern' variable has an initializer}} extern int global_count_cbon_extern = 0; -// expected-error@+2{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExplicitInitExtern' with type 'struct IncompleteStructTy *__single __counted_by_or_null(global_count_cbon_extern)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} +// expected-error@+2{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExplicitInitExtern' with type 'struct IncompleteStructTy *__single __counted_by_or_null(global_count_cbon_extern)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-warning@+1 2{{'extern' variable has an initializer}} TODO: This shouldn't be emitted twice. rdar://133001618 -extern struct IncompleteStructTy* __counted_by_or_null(global_count_cbon_extern) GlobalCBONPtrExplicitInitExtern = 0x0; -// expected-error@+2{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExplicitInitTypeDefExtern' with type 'Incomplete_Struct_t *__single __counted_by_or_null(global_count_cbon_extern)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before this definition or using the '__sized_by_or_null' attribut}} +extern struct IncompleteStructTy* __counted_by_or_null(global_count_cbon_extern) GlobalCBONPtrExplicitInitExtern = 0x0; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} +// expected-error@+2{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExplicitInitTypeDefExtern' with type 'Incomplete_Struct_t *__single __counted_by_or_null(global_count_cbon_extern)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} // expected-warning@+1 2{{'extern' variable has an initializer}} TODO: This shouldn't be emitted twice. rdar://133001618 -extern Incomplete_Struct_t* __counted_by_or_null(global_count_cbon_extern) GlobalCBONPtrExplicitInitTypeDefExtern = 0x0; +extern Incomplete_Struct_t* __counted_by_or_null(global_count_cbon_extern) GlobalCBONPtrExplicitInitTypeDefExtern = 0x0; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} // TODO: We should consider allowing this given that the pointee type size isn't // really needed when the count is 0 (rdar://129424147) -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'GlobalCBONPtrImplicitInitConstantZeroCount' with type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribut}} -struct IncompleteStructTy* __counted_by_or_null(0) GlobalCBONPtrImplicitInitConstantZeroCount; -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'GlobalCBONPtrImplicitInitConstantZeroCountTypeDef' with type 'Incomplete_Struct_t *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before this definition or using the '__sized_by_or_null' attribute}} -Incomplete_Struct_t* __counted_by_or_null(0) GlobalCBONPtrImplicitInitConstantZeroCountTypeDef; -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExplicitInitConstantZeroCount' with type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} -struct IncompleteStructTy* __counted_by_or_null(0) GlobalCBONPtrExplicitInitConstantZeroCount = 0x0; -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExplicitInitConstantZeroCountTypeDef' with type 'Incomplete_Struct_t *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before this definition or using the '__sized_by_or_null' attribute}} -Incomplete_Struct_t* __counted_by_or_null(0) GlobalCBONPtrExplicitInitConstantZeroCountTypeDef = 0x0; +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'GlobalCBONPtrImplicitInitConstantZeroCount' with type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by_or_null(0) GlobalCBONPtrImplicitInitConstantZeroCount; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'GlobalCBONPtrImplicitInitConstantZeroCountTypeDef' with type 'Incomplete_Struct_t *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} +Incomplete_Struct_t* __counted_by_or_null(0) GlobalCBONPtrImplicitInitConstantZeroCountTypeDef; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExplicitInitConstantZeroCount' with type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by_or_null(0) GlobalCBONPtrExplicitInitConstantZeroCount = 0x0; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExplicitInitConstantZeroCountTypeDef' with type 'Incomplete_Struct_t *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} +Incomplete_Struct_t* __counted_by_or_null(0) GlobalCBONPtrExplicitInitConstantZeroCountTypeDef = 0x0; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} // Unlike `__counted_by` assigning 0x0 (implicitly or explicitly) is allowed for `__counted_by_or_null` -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'GlobalCBONPtrImplicitInitConstantNonZeroCount' with type 'struct IncompleteStructTy *__single __counted_by_or_null(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} -struct IncompleteStructTy* __counted_by_or_null(5) GlobalCBONPtrImplicitInitConstantNonZeroCount; -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'GlobalCBONPtrImplicitInitConstantNonZeroCountTypeDef' with type 'Incomplete_Struct_t *__single __counted_by_or_null(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before this definition or using the '__sized_by_or_null' attribute}} -Incomplete_Struct_t* __counted_by_or_null(5) GlobalCBONPtrImplicitInitConstantNonZeroCountTypeDef; -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExplicitInitConstantNonZeroCount' with type 'struct IncompleteStructTy *__single __counted_by_or_null(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} -struct IncompleteStructTy* __counted_by_or_null(5) GlobalCBONPtrExplicitInitConstantNonZeroCount = 0x0; -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExplicitInitConstantNonZeroCountTypeDef' with type 'Incomplete_Struct_t *__single __counted_by_or_null(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before this definition or using the '__sized_by_or_null' attribute}} -Incomplete_Struct_t* __counted_by_or_null(5) GlobalCBONPtrExplicitInitConstantNonZeroCountTypeDef = 0x0; +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'GlobalCBONPtrImplicitInitConstantNonZeroCount' with type 'struct IncompleteStructTy *__single __counted_by_or_null(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by_or_null(5) GlobalCBONPtrImplicitInitConstantNonZeroCount; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'GlobalCBONPtrImplicitInitConstantNonZeroCountTypeDef' with type 'Incomplete_Struct_t *__single __counted_by_or_null(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} +Incomplete_Struct_t* __counted_by_or_null(5) GlobalCBONPtrImplicitInitConstantNonZeroCountTypeDef; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExplicitInitConstantNonZeroCount' with type 'struct IncompleteStructTy *__single __counted_by_or_null(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} +struct IncompleteStructTy* __counted_by_or_null(5) GlobalCBONPtrExplicitInitConstantNonZeroCount = 0x0; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExplicitInitConstantNonZeroCountTypeDef' with type 'Incomplete_Struct_t *__single __counted_by_or_null(5)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete}} +Incomplete_Struct_t* __counted_by_or_null(5) GlobalCBONPtrExplicitInitConstantNonZeroCountTypeDef = 0x0; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} //------------------------------------------------------------------------------ // No explicit forward decl //------------------------------------------------------------------------------ -// expected-note@+1 2{{forward declaration of 'NoExplicitForwardDecl_t' (aka 'struct NoExplicitForwardDecl')}} +// expected-note@+1 2{{consider providing a complete definition for 'NoExplicitForwardDecl_t' (aka 'struct NoExplicitForwardDecl')}} typedef struct NoExplicitForwardDecl NoExplicitForwardDecl_t; -extern NoExplicitForwardDecl_t* __counted_by(0) NoExplicitForwardDeclGlobalCBPtr; // expected-note{{__counted_by attribute is here}} +extern NoExplicitForwardDecl_t* __counted_by(0) NoExplicitForwardDeclGlobalCBPtr; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} void consume_NoExplicitForwardDeclGlobalCBPtr(void) { - // expected-error@+1{{cannot assign to 'NoExplicitForwardDeclGlobalCBPtr' that has type 'NoExplicitForwardDecl_t *__single __counted_by(0)' (aka 'struct NoExplicitForwardDecl *__single') because the pointee type 'NoExplicitForwardDecl_t' (aka 'struct NoExplicitForwardDecl') is incomplete and the '__counted_by' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'NoExplicitForwardDecl_t' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot assign to 'NoExplicitForwardDeclGlobalCBPtr' with '__counted_by' attributed type 'NoExplicitForwardDecl_t *__single __counted_by(0)' (aka 'struct NoExplicitForwardDecl *__single') because the pointee type 'NoExplicitForwardDecl_t' (aka 'struct NoExplicitForwardDecl') is incomplete}} NoExplicitForwardDeclGlobalCBPtr = 0x0; } -extern NoExplicitForwardDecl_t* __counted_by_or_null(0) NoExplicitForwardDeclGlobalCBONPtr; // expected-note{{__counted_by_or_null attribute is here}} +extern NoExplicitForwardDecl_t* __counted_by_or_null(0) NoExplicitForwardDeclGlobalCBONPtr; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} void consume_NoExplicitForwardDeclGlobalCBONPtr(void) { - // expected-error@+1{{cannot assign to 'NoExplicitForwardDeclGlobalCBONPtr' that has type 'NoExplicitForwardDecl_t *__single __counted_by_or_null(0)' (aka 'struct NoExplicitForwardDecl *__single') because the pointee type 'NoExplicitForwardDecl_t' (aka 'struct NoExplicitForwardDecl') is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'NoExplicitForwardDecl_t' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot assign to 'NoExplicitForwardDeclGlobalCBONPtr' with '__counted_by_or_null' attributed type 'NoExplicitForwardDecl_t *__single __counted_by_or_null(0)' (aka 'struct NoExplicitForwardDecl *__single') because the pointee type 'NoExplicitForwardDecl_t' (aka 'struct NoExplicitForwardDecl') is incomplete}} NoExplicitForwardDeclGlobalCBONPtr = 0x0; } @@ -1322,84 +1322,84 @@ void explicit_cast_cbon_to_bidi(struct IncompleteStructTy* p) { // Completing the pointee type allows usage //------------------------------------------------------------------------------ -// expected-note@+1 20{{forward declaration of 'struct IncompleteLaterCompletedStructTy'}} +// expected-note@+1 20{{consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy'}} struct IncompleteLaterCompletedStructTy; // Confirm using the type is an error at this point -// expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExpectErr' with type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' before this definition or using the '__sized_by' attribute}} -struct IncompleteLaterCompletedStructTy*__counted_by(0) GlobalCBPtrExpectErr = 0x0; -struct IncompleteLaterCompletedStructTy*__counted_by(0) GlobalCBPtrTentativeDefUseWillErr; // expected-note{{__counted_by attribute is here}} +// expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'GlobalCBPtrExpectErr' with type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} +struct IncompleteLaterCompletedStructTy*__counted_by(0) GlobalCBPtrExpectErr = 0x0; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} +struct IncompleteLaterCompletedStructTy*__counted_by(0) GlobalCBPtrTentativeDefUseWillErr; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExpectErr' with type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' before this definition or using the '__sized_by_or_null' attribute}} -struct IncompleteLaterCompletedStructTy*__counted_by_or_null(0) GlobalCBONPtrExpectErr = 0x0; -struct IncompleteLaterCompletedStructTy*__counted_by_or_null(0) GlobalCBONPtrTentativeDefUseWillErr; // expected-note{{__counted_by_or_null attribute is here}} +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'GlobalCBONPtrExpectErr' with type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} +struct IncompleteLaterCompletedStructTy*__counted_by_or_null(0) GlobalCBONPtrExpectErr = 0x0; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} +struct IncompleteLaterCompletedStructTy*__counted_by_or_null(0) GlobalCBONPtrTentativeDefUseWillErr; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} struct StructPtrIncompleteLaterCompleted { int count; - struct IncompleteLaterCompletedStructTy*__counted_by(count) ptr; // expected-note 2{{__counted_by attribute is here}} + struct IncompleteLaterCompletedStructTy*__counted_by(count) ptr; // expected-note 2{{consider using '__sized_by' instead of '__counted_by'}} }; struct StructCBONPtrIncompleteLaterCompleted { int count; - struct IncompleteLaterCompletedStructTy*__counted_by_or_null(count) ptr; // expected-note 2{{__counted_by_or_null attribute is here}} + struct IncompleteLaterCompletedStructTy*__counted_by_or_null(count) ptr; // expected-note 2{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} }; -void consume_IncompleteLaterCompletedStructTy(struct IncompleteLaterCompletedStructTy*__counted_by(0) p); // expected-note{{__counted_by attribute is here}} -void consume_CBON_IncompleteLaterCompletedStructTy(struct IncompleteLaterCompletedStructTy*__counted_by_or_null(0) p); // expected-note{{__counted_by_or_null attribute is here}} +void consume_IncompleteLaterCompletedStructTy(struct IncompleteLaterCompletedStructTy*__counted_by(0) p); // expected-note{{consider using '__sized_by' instead of '__counted_by'}} +void consume_CBON_IncompleteLaterCompletedStructTy(struct IncompleteLaterCompletedStructTy*__counted_by_or_null(0) p); // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} -struct IncompleteLaterCompletedStructTy*__counted_by(0) ret_IncompleteLaterCompletedStructTy(void); // expected-note{{__counted_by attribute is here}} -struct IncompleteLaterCompletedStructTy*__counted_by_or_null(0) ret_CBON_IncompleteLaterCompletedStructTy(void); // expected-note{{__counted_by_or_null attribute is here}} +struct IncompleteLaterCompletedStructTy*__counted_by(0) ret_IncompleteLaterCompletedStructTy(void); // expected-note{{consider using '__sized_by' instead of '__counted_by'}} +struct IncompleteLaterCompletedStructTy*__counted_by_or_null(0) ret_CBON_IncompleteLaterCompletedStructTy(void); // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} -// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') on a function definition because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' before the function body or using the '__sized_by' attribute}} -struct IncompleteLaterCompletedStructTy*__counted_by(0) test_cb_expect_err( // expected-note{{__counted_by attribute is here}} - // expected-error@+1{{cannot apply '__counted_by' attribute to parameter 'param' with type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') on a function definition because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' before the function body or using the '__sized_by' attribute}} - struct IncompleteLaterCompletedStructTy*__counted_by(0) param) { - // expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'local' with type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' before this definition or using the '__sized_by' attribute}} - struct IncompleteLaterCompletedStructTy*__counted_by(0) local; +// expected-error@+1{{cannot apply '__counted_by' attribute to return type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') on a function definition because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} +struct IncompleteLaterCompletedStructTy*__counted_by(0) test_cb_expect_err( // expected-note 2{{consider using '__sized_by' instead of '__counted_by'}} + // expected-error@+1{{cannot apply '__counted_by' attribute to parameter 'param' with type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') on a function definition because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} + struct IncompleteLaterCompletedStructTy*__counted_by(0) param) { // expected-note{{consider using '__sized_by' instead of '__counted_by'}} + // expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'local' with type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} + struct IncompleteLaterCompletedStructTy*__counted_by(0) local; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} - // expected-error@+1{{cannot assign to 'GlobalCBPtrTentativeDefUseWillErr' that has type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot assign to 'GlobalCBPtrTentativeDefUseWillErr' with '__counted_by' attributed type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} GlobalCBPtrTentativeDefUseWillErr = 0; - // expected-error@+1{{annot initialize 'StructPtrIncompleteLaterCompleted::ptr' that has type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(count)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot initialize 'StructPtrIncompleteLaterCompleted::ptr' with '__counted_by' attributed type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(count)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} struct StructPtrIncompleteLaterCompleted tmp = { .count = 0, .ptr = 0x0 }; struct StructPtrIncompleteLaterCompleted tmp2; - // expected-error@+1{{cannot use 'tmp2.ptr' with type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(count)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot use 'tmp2.ptr' with '__counted_by' attributed type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(count)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} consume_IncompleteLaterCompletedStructTy(tmp2.ptr); - // expected-error@+1{{cannot pass argument to parameter 'p' that has type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when passing; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot pass argument to parameter 'p' with '__counted_by' attributed type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} consume_IncompleteLaterCompletedStructTy(0x0); - // expected-error@+1{{cannot call 'ret_IncompleteLaterCompletedStructTy' with return type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot call 'ret_IncompleteLaterCompletedStructTy' with '__counted_by' attributed return type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} ret_IncompleteLaterCompletedStructTy(); - // expected-error@+1{{cannot return type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when returning; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot return '__counted_by' attributed type 'struct IncompleteLaterCompletedStructTy *__single __counted_by(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} return 0x0; } -// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to return type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') on a function definition because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' before the function body or using the '__sized_by_or_null' attribute}} -struct IncompleteLaterCompletedStructTy*__counted_by_or_null(0) test_cbon_expect_err( // expected-note{{__counted_by_or_null attribute is here}} - // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to parameter 'param' with type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') on a function definition because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' before the function body or using the '__sized_by_or_null' attribute}} - struct IncompleteLaterCompletedStructTy*__counted_by_or_null(0) param) { - // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'local' with type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' before this definition or using the '__sized_by_or_null' attribute}} - struct IncompleteLaterCompletedStructTy*__counted_by_or_null(0) local; +// expected-error@+1{{cannot apply '__counted_by_or_null' attribute to return type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') on a function definition because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} +struct IncompleteLaterCompletedStructTy*__counted_by_or_null(0) test_cbon_expect_err( // expected-note 2{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} + // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to parameter 'param' with type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') on a function definition because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} + struct IncompleteLaterCompletedStructTy*__counted_by_or_null(0) param) { // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} + // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'local' with type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} + struct IncompleteLaterCompletedStructTy*__counted_by_or_null(0) local; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} - // expected-error@+1{{cannot assign to 'GlobalCBONPtrTentativeDefUseWillErr' that has type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot assign to 'GlobalCBONPtrTentativeDefUseWillErr' with '__counted_by_or_null' attributed type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} GlobalCBONPtrTentativeDefUseWillErr = 0; - // expected-error@+1{{cannot initialize 'StructCBONPtrIncompleteLaterCompleted::ptr' that has type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when initializing; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot initialize 'StructCBONPtrIncompleteLaterCompleted::ptr' with '__counted_by_or_null' attributed type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} struct StructCBONPtrIncompleteLaterCompleted tmp = { .count = 0, .ptr = 0x0 }; struct StructCBONPtrIncompleteLaterCompleted tmp2; - // expected-error@+1{{cannot use 'tmp2.ptr' with type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot use 'tmp2.ptr' with '__counted_by_or_null' attributed type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(count)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} consume_CBON_IncompleteLaterCompletedStructTy(tmp2.ptr); - // expected-error@+1{{cannot pass argument to parameter 'p' that has type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when passing; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot pass argument to parameter 'p' with '__counted_by_or_null' attributed type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} consume_CBON_IncompleteLaterCompletedStructTy(0x0); - // expected-error@+1{{cannot call 'ret_CBON_IncompleteLaterCompletedStructTy' with return type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot call 'ret_CBON_IncompleteLaterCompletedStructTy' with '__counted_by_or_null' attributed return type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} ret_CBON_IncompleteLaterCompletedStructTy(); - // expected-error@+1{{cannot return type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when returning; consider providing a complete definition for 'struct IncompleteLaterCompletedStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot return '__counted_by_or_null' attributed type 'struct IncompleteLaterCompletedStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteLaterCompletedStructTy *__single') because the pointee type 'struct IncompleteLaterCompletedStructTy' is incomplete}} return 0x0; } diff --git a/clang/test/BoundsSafety/Sema/counted_by_type_incomplete_completable_struct_blocks.c b/clang/test/BoundsSafety/Sema/counted_by_type_incomplete_completable_struct_blocks.c index 244db35a21b29..d5bcb1a9a28c4 100644 --- a/clang/test/BoundsSafety/Sema/counted_by_type_incomplete_completable_struct_blocks.c +++ b/clang/test/BoundsSafety/Sema/counted_by_type_incomplete_completable_struct_blocks.c @@ -7,7 +7,7 @@ // pointee type on block parameters/return type //------------------------------------------------------------------------------ -struct IncompleteStructTy; // expected-note 6{{forward declaration of 'struct IncompleteStructTy'}} +struct IncompleteStructTy; // expected-note 6{{consider providing a complete definition for 'struct IncompleteStructTy'}} //------------------------------------------------------------------------------ // Attribute on block parameters @@ -20,8 +20,8 @@ void consume_cb(struct IncompleteStructTy* __counted_by(size), int size); void consume_cbon(struct IncompleteStructTy* __counted_by_or_null(size), int size); void use_block_params_cb(void) { - // expected-error@+1{{cannot apply '__counted_by' attribute to parameter 'buf' with type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by' attribute}} - cb_block_fn_t f_named = ^(struct IncompleteStructTy* __counted_by(size) buf, int size) { + // expected-error@+1{{cannot apply '__counted_by' attribute to parameter 'buf' with type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} + cb_block_fn_t f_named = ^(struct IncompleteStructTy* __counted_by(size) buf, int size) { // expected-note{{consider using '__sized_by' instead of '__counted_by'}} // Uses don't generate diagnostics because the parameter is treated as invalid. buf = 0x0; buf[0] = 0; @@ -29,14 +29,14 @@ void use_block_params_cb(void) { consume_cb(buf); }; - // expected-error@+2{{cannot apply '__counted_by' attribute to parameter with type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by' attribute}} + // expected-error@+2{{cannot apply '__counted_by' attribute to parameter with type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-warning@+1{{omitting the parameter name in a function definition is a C23 extension}} - cb_block_fn_t f_unnamed = ^(struct IncompleteStructTy* __counted_by(size), int size) { + cb_block_fn_t f_unnamed = ^(struct IncompleteStructTy* __counted_by(size), int size) { // expected-note{{consider using '__sized_by' instead of '__counted_by'}} }; void (^f_var_no_typedef_decl)(struct IncompleteStructTy* __counted_by(size), int size) = - // expected-error@+1{{cannot apply '__counted_by' attribute to parameter 'buf' with type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by' attribute}} - ^(struct IncompleteStructTy* __counted_by(size) buf, int size) { + // expected-error@+1{{cannot apply '__counted_by' attribute to parameter 'buf' with type 'struct IncompleteStructTy *__single __counted_by(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} + ^(struct IncompleteStructTy* __counted_by(size) buf, int size) { // expected-note{{consider using '__sized_by' instead of '__counted_by'}} // Uses don't generate diagnostics because the parameter is treated as invalid. buf = 0x0; buf[0] = 0; @@ -46,8 +46,8 @@ void use_block_params_cb(void) { } void use_block_params_cbon(void) { - // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to parameter 'buf' with type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by_or_null' attribute}} - cbon_block_fn_t f_named = ^(struct IncompleteStructTy* __counted_by_or_null(size) buf, int size) { + // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to parameter 'buf' with type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} + cbon_block_fn_t f_named = ^(struct IncompleteStructTy* __counted_by_or_null(size) buf, int size) { // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} // Uses don't generate diagnostics because the parameter is treated as invalid. buf = 0x0; buf[0] = 0; @@ -55,14 +55,14 @@ void use_block_params_cbon(void) { consume_cb(buf); }; - // expected-error@+2{{cannot apply '__counted_by_or_null' attribute to parameter with type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by_or_null' attribute}} + // expected-error@+2{{cannot apply '__counted_by_or_null' attribute to parameter with type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} // expected-warning@+1{{omitting the parameter name in a function definition is a C23 extension}} - cbon_block_fn_t f_unnamed = ^(struct IncompleteStructTy* __counted_by_or_null(size), int size) { + cbon_block_fn_t f_unnamed = ^(struct IncompleteStructTy* __counted_by_or_null(size), int size) { // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} }; void (^f_var_no_typedef_decl)(struct IncompleteStructTy* __counted_by_or_null(size), int size) = - // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to parameter 'buf' with type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before the function body or using the '__sized_by_or_null' attribute}} - ^(struct IncompleteStructTy* __counted_by_or_null(size) buf, int size) { + // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to parameter 'buf' with type 'struct IncompleteStructTy *__single __counted_by_or_null(size)' (aka 'struct IncompleteStructTy *__single') on a function definition because the pointee type 'struct IncompleteStructTy' is incomplete}} + ^(struct IncompleteStructTy* __counted_by_or_null(size) buf, int size) { // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} // Uses don't generate diagnostics because the parameter is treated as invalid. buf = 0x0; buf[0] = 0; diff --git a/clang/test/BoundsSafety/Sema/counted_by_type_incomplete_completable_struct_tentative_defs.c b/clang/test/BoundsSafety/Sema/counted_by_type_incomplete_completable_struct_tentative_defs.c index 72cee741e2ab8..10abf1674da4e 100644 --- a/clang/test/BoundsSafety/Sema/counted_by_type_incomplete_completable_struct_tentative_defs.c +++ b/clang/test/BoundsSafety/Sema/counted_by_type_incomplete_completable_struct_tentative_defs.c @@ -10,8 +10,8 @@ // the typedef. This seems like the right behavior because the typedef isn't the // forward declaration, `struct IncompleteStructTy` is. // -// expected-note@+2 2{{forward declaration of 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy')}} -// expected-note@+1 30{{forward declaration of 'struct IncompleteStructTy'}} +// expected-note@+2 2{{consider providing a complete definition for 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy')}} +// expected-note@+1 30{{consider providing a complete definition for 'struct IncompleteStructTy'}} struct IncompleteStructTy; //------------------------------------------------------------------------------ @@ -19,18 +19,18 @@ struct IncompleteStructTy; //------------------------------------------------------------------------------ // expected-error@+1{{cannot apply '__counted_by' attribute to tentative variable definition 'cb_t_dfn_one' with type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} -struct IncompleteStructTy*__counted_by(0) cb_t_dfn_one; // expected-note{{__counted_by attribute is here}} +struct IncompleteStructTy*__counted_by(0) cb_t_dfn_one; // expected-note 2{{consider using '__sized_by' instead of '__counted_by'}} // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'cbon_t_dfn_one' with type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} -struct IncompleteStructTy*__counted_by_or_null(0) cbon_t_dfn_one; // expected-note{{__counted_by_or_null attribute is here}} +struct IncompleteStructTy*__counted_by_or_null(0) cbon_t_dfn_one; // expected-note 2{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} void use_cb_t_dfn_one(void) { - // expected-error@+1{{cannot assign to 'cb_t_dfn_one' that has type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot assign to 'cb_t_dfn_one' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} cb_t_dfn_one = 0x0; } void use_cbon_t_dfn_one(void) { - // expected-error@+1{{cannot assign to 'cbon_t_dfn_one' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot assign to 'cbon_t_dfn_one' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} cbon_t_dfn_one = 0x0; } @@ -43,19 +43,19 @@ void use_cbon_t_dfn_one(void) { struct IncompleteStructTy*__counted_by(0) cb_t_dfn_two; // OK - tentative definition acts like declaration // expected-error@+1{{cannot apply '__counted_by' attribute to tentative variable definition 'cb_t_dfn_two' with type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} -struct IncompleteStructTy*__counted_by(0) cb_t_dfn_two; // expected-note{{__counted_by attribute is here}} +struct IncompleteStructTy*__counted_by(0) cb_t_dfn_two; // expected-note 2{{consider using '__sized_by' instead of '__counted_by'}} struct IncompleteStructTy*__counted_by_or_null(0) cbon_t_dfn_two; // OK - tentative definition acts like declaration // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'cbon_t_dfn_two' with type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} -struct IncompleteStructTy*__counted_by_or_null(0) cbon_t_dfn_two; // expected-note{{__counted_by_or_null attribute is here}} +struct IncompleteStructTy*__counted_by_or_null(0) cbon_t_dfn_two; // expected-note 2{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} void use_cb_t_dfn_two(void) { - // expected-error@+1{{cannot assign to 'cb_t_dfn_two' that has type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot assign to 'cb_t_dfn_two' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} cb_t_dfn_two = 0x0; } void use_cbon_t_dfn_two(void) { - // expected-error@+1{{cannot assign to 'cbon_t_dfn_two' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot assign to 'cbon_t_dfn_two' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} cbon_t_dfn_two = 0x0; } @@ -66,24 +66,24 @@ void use_cbon_t_dfn_two(void) { // NOTE: The diagnostic about initializing `cb_t_dfn_after_def` is suppressed. // expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'cb_t_dfn_after_def' with type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} -struct IncompleteStructTy*__counted_by(0) cb_t_dfn_after_def = 0x0; +struct IncompleteStructTy*__counted_by(0) cb_t_dfn_after_def = 0x0; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} struct IncompleteStructTy*__counted_by(0) cb_t_dfn_after_def; // OK - tentative definition acts like declaration -// expected-note@+1{{__counted_by attribute is here}} +// expected-note@+1{{consider using '__sized_by' instead of '__counted_by'}} extern struct IncompleteStructTy*__counted_by(0) cb_t_dfn_after_def; // OK - declaration // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'cbon_t_dfn_after_def' with type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} -struct IncompleteStructTy*__counted_by_or_null(0) cbon_t_dfn_after_def = 0x0; +struct IncompleteStructTy*__counted_by_or_null(0) cbon_t_dfn_after_def = 0x0; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} struct IncompleteStructTy*__counted_by_or_null(0) cbon_t_dfn_after_def; // OK - tentative definition acts like declaration // expected-note@+1{{__counted_by_or_null}} extern struct IncompleteStructTy*__counted_by_or_null(0) cbon_t_dfn_after_def; // OK - declaration void use_cb_t_dfn_after_def(void) { - // expected-error@+1{{cannot assign to 'cb_t_dfn_after_def' that has type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot assign to 'cb_t_dfn_after_def' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} cb_t_dfn_after_def = 0x0; } void use_cbon_t_dfn_after_def(void) { - // expected-error@+1{{cannot assign to 'cbon_t_dfn_after_def' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot assign to 'cbon_t_dfn_after_def' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} cbon_t_dfn_after_def = 0x0; } @@ -97,21 +97,21 @@ void use_cbon_t_dfn_after_def(void) { // than other `use_*` functions in this file. struct IncompleteStructTy*__counted_by(0) cb_t_dfn_before_def; // OK - tentative definition acts like declaration -// expected-note@+1 2{{__counted_by attribute is here}} +// expected-note@+1 2{{consider using '__sized_by' instead of '__counted_by'}} extern struct IncompleteStructTy*__counted_by(0) cb_t_dfn_before_def; // OK - declaration void consume_cb_const_count_zero(struct IncompleteStructTy*__counted_by(0) p); void use_cb_t_dfn_before_def_before_def(void) { - // expected-error@+1{{cannot assign to 'cb_t_dfn_before_def' that has type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot assign to 'cb_t_dfn_before_def' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} cb_t_dfn_before_def = 0x0; - // expected-error@+1{{cannot use 'cb_t_dfn_before_def' with type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot use 'cb_t_dfn_before_def' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} consume_cb_const_count_zero(cb_t_dfn_before_def); } // expected-error@+1{{cannot apply '__counted_by' attribute to variable definition 'cb_t_dfn_before_def' with type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} -struct IncompleteStructTy*__counted_by(0) cb_t_dfn_before_def = 0x0; +struct IncompleteStructTy*__counted_by(0) cb_t_dfn_before_def = 0x0; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} void use_cb_t_dfn_before_def_after_def(void) { // no error here. At this point `cb_t_dfn_before_def` has been marked as invalid @@ -121,21 +121,21 @@ void use_cb_t_dfn_before_def_after_def(void) { } struct IncompleteStructTy*__counted_by_or_null(0) cbon_t_dfn_before_def; // OK - tentative definition acts like declaration -// expected-note@+1 2{{__counted_by_or_null attribute is here}} +// expected-note@+1 2{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} extern struct IncompleteStructTy*__counted_by_or_null(0) cbon_t_dfn_before_def; // OK - declaration void consume_cbon_const_count_zero(struct IncompleteStructTy*__counted_by_or_null(0) p); void use_cbon_t_dfn_before_def_before_def(void) { - // expected-error@+1{{cannot assign to 'cbon_t_dfn_before_def' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot assign to 'cbon_t_dfn_before_def' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} cbon_t_dfn_before_def = 0x0; - // expected-error@+1{{cannot use 'cbon_t_dfn_before_def' with type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete in this context; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot use 'cbon_t_dfn_before_def' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} consume_cbon_const_count_zero(cbon_t_dfn_before_def); } // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to variable definition 'cbon_t_dfn_before_def' with type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} -struct IncompleteStructTy*__counted_by_or_null(0) cbon_t_dfn_before_def = 0x0; +struct IncompleteStructTy*__counted_by_or_null(0) cbon_t_dfn_before_def = 0x0; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} void use_cbon_t_dfn_before_def_after_def(void) { // no error here. At this point `cbon_t_dfn_before_def` has been marked as invalid @@ -151,19 +151,19 @@ void use_cbon_t_dfn_before_def_after_def(void) { static struct IncompleteStructTy*__counted_by(0) cb_t_dfn_static_def; // OK - tentative definition acts like declaration // expected-error@+1{{cannot apply '__counted_by' attribute to tentative variable definition 'cb_t_dfn_static_def' with type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} -static struct IncompleteStructTy*__counted_by(0) cb_t_dfn_static_def; // expected-note{{__counted_by attribute is here}} +static struct IncompleteStructTy*__counted_by(0) cb_t_dfn_static_def; // expected-note 2{{consider using '__sized_by' instead of '__counted_by'}} static struct IncompleteStructTy*__counted_by_or_null(0) cbon_t_dfn_static_def; // OK - tentative definition acts like declaration // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'cbon_t_dfn_static_def' with type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} -static struct IncompleteStructTy*__counted_by_or_null(0) cbon_t_dfn_static_def; // expected-note{{__counted_by_or_null attribute is here}} +static struct IncompleteStructTy*__counted_by_or_null(0) cbon_t_dfn_static_def; // expected-note 2{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} void use_cb_t_dfn_static_def(void) { - // expected-error@+1{{cannot assign to 'cb_t_dfn_static_def' that has type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot assign to 'cb_t_dfn_static_def' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} cb_t_dfn_static_def = 0x0; } void use_cbon_t_dfn_static_def(void) { - // expected-error@+1{{cannot assign to 'cbon_t_dfn_static_def' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot assign to 'cbon_t_dfn_static_def' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} cbon_t_dfn_static_def = 0x0; } @@ -173,41 +173,41 @@ void use_cbon_t_dfn_static_def(void) { static int cb_t_dfn_static_non_const_count_count; // expected-error@+1{{cannot apply '__counted_by' attribute to tentative variable definition 'cb_t_dfn_static_non_const_count' with type 'struct IncompleteStructTy *__single __counted_by(cb_t_dfn_static_non_const_count_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} -static struct IncompleteStructTy*__counted_by(cb_t_dfn_static_non_const_count_count) cb_t_dfn_static_non_const_count; // expected-note{{__counted_by attribute is here}} +static struct IncompleteStructTy*__counted_by(cb_t_dfn_static_non_const_count_count) cb_t_dfn_static_non_const_count; // expected-note 2{{consider using '__sized_by' instead of '__counted_by'}} static int cbon_t_dfn_static_non_const_count_count; // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'cbon_t_dfn_static_non_const_count' with type 'struct IncompleteStructTy *__single __counted_by_or_null(cbon_t_dfn_static_non_const_count_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} -static struct IncompleteStructTy*__counted_by_or_null(cbon_t_dfn_static_non_const_count_count) cbon_t_dfn_static_non_const_count; // expected-note{{__counted_by_or_null attribute is here}} +static struct IncompleteStructTy*__counted_by_or_null(cbon_t_dfn_static_non_const_count_count) cbon_t_dfn_static_non_const_count; // expected-note 2{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} int cb_t_dfn_non_const_count_count; // expected-error@+1{{cannot apply '__counted_by' attribute to tentative variable definition 'cb_t_dfn_non_const_count' with type 'struct IncompleteStructTy *__single __counted_by(cb_t_dfn_non_const_count_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by' attribute}} -struct IncompleteStructTy*__counted_by(cb_t_dfn_non_const_count_count) cb_t_dfn_non_const_count; // expected-note{{__counted_by attribute is here}} +struct IncompleteStructTy*__counted_by(cb_t_dfn_non_const_count_count) cb_t_dfn_non_const_count; // expected-note 2{{consider using '__sized_by' instead of '__counted_by'}} int cbon_t_dfn_non_const_count_count; // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'cbon_t_dfn_non_const_count' with type 'struct IncompleteStructTy *__single __counted_by_or_null(cbon_t_dfn_non_const_count_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete; consider providing a complete definition for 'struct IncompleteStructTy' before this definition or using the '__sized_by_or_null' attribute}} -struct IncompleteStructTy*__counted_by_or_null(cbon_t_dfn_non_const_count_count) cbon_t_dfn_non_const_count; // expected-note{{__counted_by_or_null attribute is here}} +struct IncompleteStructTy*__counted_by_or_null(cbon_t_dfn_non_const_count_count) cbon_t_dfn_non_const_count; // expected-note 2{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} void use_cb_t_dfn_static_non_const_count(void) { - // expected-error@+1{{cannot assign to 'cb_t_dfn_static_non_const_count' that has type 'struct IncompleteStructTy *__single __counted_by(cb_t_dfn_static_non_const_count_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot assign to 'cb_t_dfn_static_non_const_count' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(cb_t_dfn_static_non_const_count_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} cb_t_dfn_static_non_const_count = 0x0; cb_t_dfn_static_non_const_count_count = 0; } void use_cbon_t_dfn_static_non_const_count(void) { - // expected-error@+1{{cannot assign to 'cbon_t_dfn_static_non_const_count' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(cbon_t_dfn_static_non_const_count_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot assign to 'cbon_t_dfn_static_non_const_count' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(cbon_t_dfn_static_non_const_count_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} cbon_t_dfn_static_non_const_count = 0x0; cbon_t_dfn_static_non_const_count_count = 0; } void use_cb_t_dfn_non_const_count(void) { - // expected-error@+1{{cannot assign to 'cb_t_dfn_non_const_count' that has type 'struct IncompleteStructTy *__single __counted_by(cb_t_dfn_non_const_count_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by' attribute}} + // expected-error@+1{{cannot assign to 'cb_t_dfn_non_const_count' with '__counted_by' attributed type 'struct IncompleteStructTy *__single __counted_by(cb_t_dfn_non_const_count_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} cb_t_dfn_non_const_count = 0x0; cb_t_dfn_non_const_count_count = 0; } void use_cbon_t_dfn_non_const_count(void) { - // expected-error@+1{{cannot assign to 'cbon_t_dfn_non_const_count' that has type 'struct IncompleteStructTy *__single __counted_by_or_null(cbon_t_dfn_non_const_count_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete and the '__counted_by_or_null' attribute requires the pointee type be complete when assigning; consider providing a complete definition for 'struct IncompleteStructTy' or using the '__sized_by_or_null' attribute}} + // expected-error@+1{{cannot assign to 'cbon_t_dfn_non_const_count' with '__counted_by_or_null' attributed type 'struct IncompleteStructTy *__single __counted_by_or_null(cbon_t_dfn_non_const_count_count)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'struct IncompleteStructTy' is incomplete}} cbon_t_dfn_non_const_count = 0x0; cbon_t_dfn_non_const_count_count = 0; } @@ -219,10 +219,10 @@ void use_cbon_t_dfn_non_const_count(void) { typedef struct IncompleteStructTy Incomplete_Struct_t; // expected-error@+1{{cannot apply '__counted_by' attribute to tentative variable definition 'cb_t_dfn_one_typedef' with type 'Incomplete_Struct_t *__single __counted_by(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before this definition or using the '__sized_by' attribute}} -Incomplete_Struct_t*__counted_by(0) cb_t_dfn_one_typedef; +Incomplete_Struct_t*__counted_by(0) cb_t_dfn_one_typedef; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'cbon_t_dfn_one_typedef' with type 'Incomplete_Struct_t *__single __counted_by_or_null(0)' (aka 'struct IncompleteStructTy *__single') because the pointee type 'Incomplete_Struct_t' (aka 'struct IncompleteStructTy') is incomplete; consider providing a complete definition for 'Incomplete_Struct_t' before this definition or using the '__sized_by_or_null' attribute}} -Incomplete_Struct_t*__counted_by_or_null(0) cbon_t_dfn_one_typedef; +Incomplete_Struct_t*__counted_by_or_null(0) cbon_t_dfn_one_typedef; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} //------------------------------------------------------------------------------ diff --git a/clang/test/BoundsSafety/Sema/counted_by_type_unknown_completable_union.c b/clang/test/BoundsSafety/Sema/counted_by_type_unknown_completable_union.c index 674ac0fe6388a..3a8e13550166b 100644 --- a/clang/test/BoundsSafety/Sema/counted_by_type_unknown_completable_union.c +++ b/clang/test/BoundsSafety/Sema/counted_by_type_unknown_completable_union.c @@ -5,15 +5,15 @@ // Test incomplete unions extern int external_union_len; -typedef union incomplete_union incomplete_union_t; // expected-note 2{{forward declaration of 'union incomplete_union'}} +typedef union incomplete_union incomplete_union_t; // expected-note 2{{consider providing a complete definition for 'union incomplete_union'}} extern incomplete_union_t* __counted_by(external_union_len) incompleteUnionPtr; // OK extern union incomplete_union* __counted_by(external_union_len) incompleteUnionPtr2; // OK int global_union_len; // expected-error@+1{{cannot apply '__counted_by' attribute to tentative variable definition 'GlobalCBUnionPtrImplicitInit' with type 'union incomplete_union *__single __counted_by(global_union_len)' (aka 'union incomplete_union *__single') because the pointee type 'union incomplete_union' is incomplete; consider providing a complete definition for 'union incomplete_union' before this definition or using the '__sized_by' attribute}} -union incomplete_union* __counted_by(global_union_len) GlobalCBUnionPtrImplicitInit; +union incomplete_union* __counted_by(global_union_len) GlobalCBUnionPtrImplicitInit; // expected-note{{consider using '__sized_by' instead of '__counted_by'}} // expected-error@+1{{cannot apply '__counted_by_or_null' attribute to tentative variable definition 'GlobalCBONUnionPtrImplicitInit' with type 'union incomplete_union *__single __counted_by_or_null(global_union_len)' (aka 'union incomplete_union *__single') because the pointee type 'union incomplete_union' is incomplete; consider providing a complete definition for 'union incomplete_union' before this definition or using the '__sized_by_or_null' attribute}} -union incomplete_union* __counted_by_or_null(global_union_len) GlobalCBONUnionPtrImplicitInit; +union incomplete_union* __counted_by_or_null(global_union_len) GlobalCBONUnionPtrImplicitInit; // expected-note{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} // Unions are handled like structs for the diagnostics so the testing for structs // should mean testing other combinations should be unnecessary. diff --git a/clang/test/BoundsSafety/Sema/source-location-for-counted-attribute-type.c b/clang/test/BoundsSafety/Sema/source-location-for-counted-attribute-type.c index a6ba2efc6c53b..debc307b39a70 100644 --- a/clang/test/BoundsSafety/Sema/source-location-for-counted-attribute-type.c +++ b/clang/test/BoundsSafety/Sema/source-location-for-counted-attribute-type.c @@ -22,24 +22,24 @@ struct IncompleteTy; // Incomplete #define COUNT_ARG 0 struct CB { int count; - // CHECK: [[@LINE+1]]:26: note: __counted_by attribute is here + // CHECK: [[@LINE+1]]:26: note: consider using '__sized_by' instead of '__counted_by' struct IncompleteTy* __counted_by(count) b_macro; - // CHECK: [[@LINE+1]]:41: note: __counted_by attribute is here + // CHECK: [[@LINE+1]]:41: note: consider using '__sized_by' instead of '__counted_by' struct IncompleteTy* __attribute__((counted_by(count))) b_direct_non_affixed; - // CHECK: [[@LINE+1]]:41: note: __counted_by attribute is here + // CHECK: [[@LINE+1]]:41: note: consider using '__sized_by' instead of '__counted_by' struct IncompleteTy* __attribute__((__counted_by__(count))) b_direct_affixed; // NOTE: In these cases the locations just point to the count expressions as // a fallback. - // CHECK: [[@LINE+1]]:44: note: __counted_by attribute is here + // CHECK: [[@LINE+1]]:44: note: consider using '__sized_by' instead of '__counted_by' struct IncompleteTy* custom_counted_by(count) b_custom_macro; - // CHECK: [[@LINE+1]]:46: note: __counted_by attribute is here + // CHECK: [[@LINE+1]]:46: note: consider using '__sized_by' instead of '__counted_by' struct IncompleteTy* custom_counted_by__(count) b_custom_macro_underscored; - // CHECK: [[@LINE+1]]:39: note: __counted_by attribute is here + // CHECK: [[@LINE+1]]:39: note: consider using '__sized_by' instead of '__counted_by' struct IncompleteTy* __counted_by(COUNT_ARG) b_macro_macro_arg; - // CHECK: [[@LINE+1]]:52: note: __counted_by attribute is here + // CHECK: [[@LINE+1]]:52: note: consider using '__sized_by' instead of '__counted_by' struct IncompleteTy* __attribute__((counted_by(COUNT_ARG))) b_direct_non_affixed_macro_arg; - // CHECK: [[@LINE+1]]:56: note: __counted_by attribute is here + // CHECK: [[@LINE+1]]:56: note: consider using '__sized_by' instead of '__counted_by' struct IncompleteTy* __attribute__((__counted_by__(COUNT_ARG))) b_direct_affixed_macro_arg; }; @@ -63,24 +63,24 @@ void useCB(struct CB* cb) { struct CBON { int count; - // CHECK: [[@LINE+1]]:26: note: __counted_by_or_null attribute is here + // CHECK: [[@LINE+1]]:26: note: consider using '__sized_by_or_null' instead of '__counted_by_or_null' struct IncompleteTy* __counted_by_or_null(count) b_macro; - // CHECK: [[@LINE+1]]:41: note: __counted_by_or_null attribute is here + // CHECK: [[@LINE+1]]:41: note: consider using '__sized_by_or_null' instead of '__counted_by_or_null' struct IncompleteTy* __attribute__((counted_by_or_null(count))) b_direct_non_affixed; - // CHECK: [[@LINE+1]]:41: note: __counted_by_or_null attribute is here + // CHECK: [[@LINE+1]]:41: note: consider using '__sized_by_or_null' instead of '__counted_by_or_null' struct IncompleteTy* __attribute__((__counted_by_or_null__(count))) b_direct_affixed; // NOTE: In these cases the locations just points to the count expressions as // a fallback. - // CHECK: [[@LINE+1]]:52: note: __counted_by_or_null attribute is here + // CHECK: [[@LINE+1]]:52: note: consider using '__sized_by_or_null' instead of '__counted_by_or_null' struct IncompleteTy* custom_counted_by_or_null(count) b_custom_macro; - // CHECK: [[@LINE+1]]:54: note: __counted_by_or_null attribute is here + // CHECK: [[@LINE+1]]:54: note: consider using '__sized_by_or_null' instead of '__counted_by_or_null' struct IncompleteTy* custom_counted_by_or_null__(count) b_custom_macro_underscored; - // CHECK: [[@LINE+1]]:47: note: __counted_by_or_null attribute is here + // CHECK: [[@LINE+1]]:47: note: consider using '__sized_by_or_null' instead of '__counted_by_or_null' struct IncompleteTy* __counted_by_or_null(COUNT_ARG) b_macro_macro_arg; - // CHECK: [[@LINE+1]]:60: note: __counted_by_or_null attribute is here + // CHECK: [[@LINE+1]]:60: note: consider using '__sized_by_or_null' instead of '__counted_by_or_null' struct IncompleteTy* __attribute__((counted_by_or_null(COUNT_ARG))) b_direct_non_affixed_macro_arg; - // CHECK: [[@LINE+1]]:64: note: __counted_by_or_null attribute is here + // CHECK: [[@LINE+1]]:64: note: consider using '__sized_by_or_null' instead of '__counted_by_or_null' struct IncompleteTy* __attribute__((__counted_by_or_null__(COUNT_ARG))) b_direct_affixed_macro_arg; }; diff --git a/clang/test/Sema/attr-counted-by-late-parsed-struct-ptrs.c b/clang/test/Sema/attr-counted-by-late-parsed-struct-ptrs.c index d0d4ef5751616..1dff82ac887ce 100644 --- a/clang/test/Sema/attr-counted-by-late-parsed-struct-ptrs.c +++ b/clang/test/Sema/attr-counted-by-late-parsed-struct-ptrs.c @@ -19,13 +19,12 @@ struct on_member_pointer_complete_ty { }; struct on_member_pointer_incomplete_ty { - struct size_unknown * buf __counted_by(count); // expected-error{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct size_unknown' is an incomplete type}} + struct size_unknown * buf __counted_by(count); // ok int count; }; struct on_member_pointer_const_incomplete_ty { - // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'const struct size_unknown' is an incomplete type}} - const struct size_unknown * buf __counted_by(count); + const struct size_unknown * buf __counted_by(count); // ok int count; }; diff --git a/clang/test/Sema/attr-counted-by-or-null-last-field.c b/clang/test/Sema/attr-counted-by-or-null-last-field.c index 12c0b6de44f72..60a1f571b19e9 100644 --- a/clang/test/Sema/attr-counted-by-or-null-last-field.c +++ b/clang/test/Sema/attr-counted-by-or-null-last-field.c @@ -118,12 +118,12 @@ struct annotated_with_anon_struct { struct count_unknown; struct on_member_ptr_incomplete_ty_ty_pos { int count; - struct count_unknown * ptr __counted_by_or_null(count); // expected-error {{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'struct count_unknown' is an incomplete type}} + struct count_unknown * ptr __counted_by_or_null(count); // ok }; struct on_member_ptr_incomplete_const_ty_ty_pos { int count; - const struct count_unknown * ptr __counted_by_or_null(count); // expected-error {{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'const struct count_unknown' is an incomplete type}} + const struct count_unknown * ptr __counted_by_or_null(count); // ok }; struct on_member_ptr_void_ty_ty_pos { diff --git a/clang/test/Sema/attr-counted-by-or-null-late-parsed-struct-ptrs.c b/clang/test/Sema/attr-counted-by-or-null-late-parsed-struct-ptrs.c index d81254631b628..c0acbb1ceea3d 100644 --- a/clang/test/Sema/attr-counted-by-or-null-late-parsed-struct-ptrs.c +++ b/clang/test/Sema/attr-counted-by-or-null-late-parsed-struct-ptrs.c @@ -20,13 +20,12 @@ struct on_member_pointer_complete_ty { }; struct on_member_pointer_incomplete_ty { - struct size_unknown * buf __counted_by_or_null(count); // expected-error{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'struct size_unknown' is an incomplete type}} + struct size_unknown * buf __counted_by_or_null(count); // ok int count; }; struct on_member_pointer_const_incomplete_ty { - // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'const struct size_unknown' is an incomplete type}} - const struct size_unknown * buf __counted_by_or_null(count); + const struct size_unknown * buf __counted_by_or_null(count); // ok int count; }; diff --git a/clang/test/Sema/attr-counted-by-or-null-struct-ptrs-completable-incomplete-pointee.c b/clang/test/Sema/attr-counted-by-or-null-struct-ptrs-completable-incomplete-pointee.c new file mode 100644 index 0000000000000..cff5a14c70b99 --- /dev/null +++ b/clang/test/Sema/attr-counted-by-or-null-struct-ptrs-completable-incomplete-pointee.c @@ -0,0 +1,631 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fexperimental-late-parse-attributes -fsyntax-only -verify %s + +#define __counted_by_or_null(f) __attribute__((counted_by_or_null(f))) + +// ============================================================================= +// # Struct incomplete type with attribute in the decl position +// ============================================================================= + +// Note: This could be considered misleading. The typedef isn't actually on this +// line. Also note the discrepancy in diagnostic count (27 vs 51) is due to +// the pointer arithmetic on incomplete pointee type diagnostic always using +// diagnostic text that refers to the underlying forward decl, even when the +// typedef is used. +// expected-note@+3 27{{consider providing a complete definition for 'Incomplete_t' (aka 'struct IncompleteTy')}} +// The 'forward declaration' notes come from 'arithmetic on a pointer to an incomplete type' errors +// expected-note@+1 24{{forward declaration of 'struct IncompleteTy'}} +struct IncompleteTy; // expected-note 27{{consider providing a complete definition for 'struct IncompleteTy'}} + +typedef struct IncompleteTy Incomplete_t; + +struct CBBufDeclPos { + int count; + struct IncompleteTy* buf __counted_by_or_null(count); // OK expected-note 27{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} + Incomplete_t* buf_typedef __counted_by_or_null(count); // OK expected-note 27{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} +}; + +void consume_struct_IncompleteTy(struct IncompleteTy* buf); + +int idx(void); + + + +void test_CBBufDeclPos(struct CBBufDeclPos* ptr) { + // =========================================================================== + // ## Local variable initialization + // =========================================================================== + struct CBBufDeclPos explicit_desig_init = { + .count = 0, + // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + .buf = 0x0, + // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + .buf_typedef = 0x0 + }; + // Variable is not currently marked as invalid so uses of the variable allows + // diagnostics to fire. + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + explicit_desig_init.buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + explicit_desig_init.buf_typedef = 0x0; + // expected-error@+1{{cannot use 'explicit_desig_init.buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + void *tmp = explicit_desig_init.buf; + // expected-error@+1{{cannot use 'explicit_desig_init.buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + void *tmp2 = explicit_desig_init.buf_typedef; + + struct CBBufDeclPos partial_explicit_desig_init = { + .count = 0, + // .buf and .buf_typedef are implicit zero initialized + // expected-error@+2{{cannot implicitly initialize 'CBBufDeclPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + // expected-error@+1{{cannot implicitly initialize 'CBBufDeclPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + }; + + struct CBBufDeclPos implicit_full_init = { + 0 + // expected-error@+2{{cannot implicitly initialize 'CBBufDeclPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + // expected-error@+1{{cannot implicitly initialize 'CBBufDeclPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + }; + // Variable is not currently marked as invalid so uses of the variable allows + // diagnostics to fire. + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + implicit_full_init.buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + implicit_full_init.buf_typedef = 0x0; + // expected-error@+1{{cannot use 'implicit_full_init.buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + void* tmp3 = implicit_full_init.buf; + // expected-error@+1{{cannot use 'implicit_full_init.buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + void* tmp4 = implicit_full_init.buf_typedef; + + struct CBBufDeclPos explicit_non_desig_init = { + 0, + // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + 0x0, + // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + 0x0 + }; + + + + + // =========================================================================== + // ## Assignment to fields + // =========================================================================== + struct CBBufDeclPos uninit; + uninit.count = 0; + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + uninit.buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + uninit.buf_typedef = 0x0; + ptr->count = 0; + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + ptr->buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + ptr->buf_typedef = 0x0; + + + // =========================================================================== + // ## Make sure modifying the fields through other assignment operators is not + // allowed + // =========================================================================== + uninit.buf++; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + ++uninit.buf; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + uninit.buf += 1; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + uninit.buf_typedef++; // // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + ++uninit.buf_typedef; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + uninit.buf_typedef -= 1; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + + uninit.buf--; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + --uninit.buf; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + uninit.buf -= 1; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + uninit.buf_typedef--; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + --uninit.buf_typedef; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + uninit.buf_typedef -= 1; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + + ptr->buf++; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + ++ptr->buf; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + ptr->buf += 1; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + ptr->buf--; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + --ptr->buf; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + ptr->buf -= 1; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + + ptr->buf_typedef++; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + ++ptr->buf_typedef; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + ptr->buf_typedef += 1; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + ptr->buf_typedef--; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + --ptr->buf_typedef; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + ptr->buf_typedef -= 1; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + + // =========================================================================== + // ## Use of fields in expressions + // =========================================================================== + // expected-error@+2{{cannot use 'uninit.buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + void* addr = + ((char*) uninit.buf ) + 1; + // expected-error@+2{{cannot use 'uninit.buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + void* addr_typedef = + ((char*) uninit.buf_typedef ) + 1; + // expected-error@+2{{cannot use 'ptr->buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + void* addr_ptr = + ((char*) ptr->buf ) + 1; + // expected-error@+2{{cannot use 'ptr->buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + void* addr_ptr_typedef = + ((char*) ptr->buf_typedef ) + 1; + + + // =========================================================================== + // ## Take address of fields + // =========================================================================== + // TODO: This should be forbidden, not because of the incomplete pointee type + // but because in the -fbounds-safety language model the address of a + // `counted_by` pointer cannot be taken to avoid it being possible to modify + // the `counted_by` pointer through another pointer. Whether or not this + // should be forbidden when `-fbounds-safety` is off is TBD. + // + // The incomplete pointee type isn't actually a problem here for + // `-fbounds-safety` because taking the address of a pointer returns a pointer + // that have the bounds of a single `void*`, so bounds checks on the resulting + // pointer don't need to know `sizeof(struct IncompleteTy)` but instead + // `sizeof(struct IncompleteTy* buf __counted_by_or_null(count))` which is just the + // size of a pointer. + void* take_addr = &uninit.buf; + void* take_addr_typedef = &uninit.buf_typedef; + void* take_addr_ptr = &ptr->buf; + void* take_addr_ptr_typedef = &ptr->buf_typedef; + + // expected-error@+1{{cannot use 'uninit.buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + struct IncompleteTy* addr_elt_zero = &uninit.buf[0]; + // expected-error@+1{{cannot use 'uninit.buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + struct IncompleteTy* addr_elt_idx = &uninit.buf[idx()]; + + // expected-error@+1{{cannot use 'uninit.buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + struct IncompleteTy* addr_elt_zero_typedef = &uninit.buf_typedef[0]; + // expected-error@+1{{cannot use 'uninit.buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + struct IncompleteTy* addr_elt_idx_typedef = &uninit.buf_typedef[idx()]; + + // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + struct IncompleteTy* addr_elt_zero_ptr = &ptr->buf[0]; + // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + struct IncompleteTy* addr_elt_idx_ptr = &ptr->buf[idx()]; + // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + struct IncompleteTy* addr_elt_zero_ptr_typedef = &ptr->buf_typedef[0]; + // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + struct IncompleteTy* addr_elt_idx_ptr_typedef = &ptr->buf_typedef[idx()]; + + + // =========================================================================== + // ## Use fields as call arguments + // =========================================================================== + // expected-error@+1{{cannot use 'uninit.buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + consume_struct_IncompleteTy(uninit.buf); + // expected-error@+1{{cannot use 'uninit.buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + consume_struct_IncompleteTy(uninit.buf_typedef); + // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + consume_struct_IncompleteTy(ptr->buf); + // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + consume_struct_IncompleteTy(ptr->buf_typedef); + + // =========================================================================== + // ## Use [] operator on fields + // =========================================================================== + // expected-error@+1 2{{cannot use 'uninit.buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + uninit.buf[0] = uninit.buf[1]; + // expected-error@+1 2{{cannot use 'uninit.buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + uninit.buf_typedef[0] = uninit.buf_typedef[1]; + // expected-error@+1 2{{cannot use 'ptr->buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + ptr->buf[0] = ptr->buf[1]; + // expected-error@+1 2{{cannot use 'ptr->buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + ptr->buf_typedef[0] = ptr->buf_typedef[1]; +} + + +// ============================================================================= +// ## Global initialization +// ============================================================================= + +struct CBBufDeclPos global_explicit_desig_init = { + .count = 0, + // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + .buf = 0x0, + // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + .buf_typedef = 0x0 +}; + +void use_global_explicit_desig_init(void) { + // Variable isn't marked as invalid so diagnostics still fire + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + global_explicit_desig_init.buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + global_explicit_desig_init.buf_typedef = 0x0; +} + +struct CBBufDeclPos global_partial_explicit_desig_init = { + .count = 0, + // .buf and .buf_typedef are implicit zero initialized + // expected-error@+2{{cannot implicitly initialize 'CBBufDeclPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + // expected-error@+1{{cannot implicitly initialize 'CBBufDeclPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} +}; + +struct CBBufDeclPos global_implicit_full_init = { + 0 + // expected-error@+2{{cannot implicitly initialize 'CBBufDeclPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + // expected-error@+1{{cannot implicitly initialize 'CBBufDeclPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} +}; + +struct CBBufDeclPos global_explicit_non_desig_init = { + 0, + // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + 0x0, + // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_t * __counted_by_or_null(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + 0x0 +}; + +extern struct CBBufDeclPos global_declaration; // OK + +// TODO: These tentative definitions are implicitly empty initialized to zero. +// This should generate an error diagnostic but currently doesn't. There should +// be a carve out to allow `__counted_by_or_null(0)` which is the only constant count +// version of the attribute where it is valid to assign NULL. +struct CBBufDeclPos global_tentative_defn; +static struct CBBufDeclPos global_tentative_defn2; + +// ============================================================================= +// ## Completing the definition of the type allows use of CBBufDeclPos fields +// ============================================================================= +struct IncompleteTy { + int field; +}; + +void test_CBBufDeclPos_completed(struct CBBufDeclPos* ptr) { + // Initialization is ok + struct CBBufDeclPos explicit_desig_init = { + .count = 0, + .buf = 0x0, + .buf_typedef = 0x0 + }; + + struct CBBufDeclPos partial_explicit_desig_init = { + .count = 0, + // .buf and .buf_typedef are implicit zero initialized + }; + + struct CBBufDeclPos implicit_full_init = {0}; + + struct CBBufDeclPos explicit_non_desig_init = { + 0, + 0x0, + 0x0 + }; + + // Assignment to fields is ok + ptr->buf = 0x0; + ptr->buf_typedef = 0x0; + + // Use of fields in expressions is ok + void* tmp = ptr->buf; + void* tmp2 = ptr->buf_typedef; + + // Take address of fields is ok + void* take_addr_ptr = &ptr->buf; + void* take_addr_ptr_typedef = &ptr->buf_typedef; + + struct IncompleteTy* addr_elt_zero_ptr = &ptr->buf[0]; + struct IncompleteTy* addr_elt_idx_ptr = &ptr->buf[idx()]; + struct IncompleteTy* addr_elt_zero_ptr_typedef = &ptr->buf_typedef[0]; + struct IncompleteTy* addr_elt_idx_ptr_typedef = &ptr->buf_typedef[idx()]; + + // As call arguments is ok + consume_struct_IncompleteTy(ptr->buf); + consume_struct_IncompleteTy(ptr->buf_typedef); + + // In [] operator is ok + ptr->buf[0] = ptr->buf[1]; + ptr->buf_typedef[0] = ptr->buf_typedef[1]; +} + +// Global initialization is ok + +struct CBBufDeclPos global_explicit_desig_init_completed = { + .count = 0, + .buf = 0x0, + .buf_typedef = 0x0 +}; + +struct CBBufDeclPos global_partial_explicit_desig_init_completed = { + .count = 0, + // .buf and .buf_typedef are implicit zero initialized +}; + +struct CBBufDeclPos global_implicit_full_init_completed = {0}; + +struct CBBufDeclPos global_explicit_non_desig_init_completed = { + 0, + 0x0, + 0x0 +}; + +extern struct CBBufDeclPos global_declaration; +struct CBBufDeclPos global_tentative_defn; +static struct CBBufDeclPos global_tentative_defn2; + +// ============================================================================= +// # Struct incomplete type with attribute in the pointer position +// ============================================================================= + +// expected-note@+1 8{{consider providing a complete definition for 'Incomplete_ty2' (aka 'struct IncompleteTy2')}} +struct IncompleteTy2; // expected-note 8{{consider providing a complete definition for 'struct IncompleteTy2'}} +typedef struct IncompleteTy2 Incomplete_ty2; + +void consume_struct_IncompleteTy2(struct IncompleteTy2* buf); + +struct CBBufTyPos { + int count; + struct IncompleteTy2* __counted_by_or_null(count) buf ; // OK expected-note 8{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} + Incomplete_ty2 *__counted_by_or_null(count) buf_typedef; // OK expected-note 8{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} +}; + +void use_CBBufTyPos(struct CBBufTyPos* ptr) { + struct CBBufTyPos explicit_desig_init = { + .count = 0, + // expected-error@+1{{cannot initialize 'CBBufTyPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy2 * __counted_by_or_null(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}} + .buf = 0x0, + // expected-error@+1{{cannot initialize 'CBBufTyPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_ty2 * __counted_by_or_null(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}} + .buf_typedef = 0x0 + }; + + // Assignment + // expected-error@+1{{cannot assign to 'CBBufTyPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy2 * __counted_by_or_null(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}} + explicit_desig_init.buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufTyPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_ty2 * __counted_by_or_null(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}} + explicit_desig_init.buf_typedef = 0x0; + // expected-error@+1{{cannot assign to 'CBBufTyPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy2 * __counted_by_or_null(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}} + ptr->buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufTyPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_ty2 * __counted_by_or_null(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}} + ptr->buf_typedef = 0x0; + + // Use + // expected-error@+2{{cannot use 'ptr->buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy2 * __counted_by_or_null(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}} + void* addr = + ((char*) ptr->buf ) + 1; + // expected-error@+2{{cannot use 'ptr->buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_ty2 * __counted_by_or_null(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}} + void* addr_typedef = + ((char*) ptr->buf_typedef ) + 1; + + // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy2 * __counted_by_or_null(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}} + consume_struct_IncompleteTy2(ptr->buf); + // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_ty2 * __counted_by_or_null(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}} + consume_struct_IncompleteTy2(ptr->buf_typedef); + + // expected-error@+1 2{{cannot use 'ptr->buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy2 * __counted_by_or_null(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}} + ptr->buf[0] = ptr->buf[1]; + // expected-error@+1 2{{cannot use 'ptr->buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_ty2 * __counted_by_or_null(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}} + ptr->buf_typedef[0] = ptr->buf_typedef[1]; +} + +struct CBBufTyPos global_explicit_desig_init_struct_type_pos = { + .count = 0, + // expected-error@+1{{cannot initialize 'CBBufTyPos::buf' with '__counted_by_or_null' attributed type 'struct IncompleteTy2 * __counted_by_or_null(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}} + .buf = 0x0, + // expected-error@+1{{cannot initialize 'CBBufTyPos::buf_typedef' with '__counted_by_or_null' attributed type 'Incomplete_ty2 * __counted_by_or_null(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}} + .buf_typedef = 0x0 +}; + +// Defining the type makes `CBBufTyPos` fields usable +struct IncompleteTy2 { + int field; +}; + +void use_CBBufTyPos_completed(struct CBBufTyPos* ptr) { + ptr->buf = 0x0; + ptr->buf_typedef = 0x0; + void* addr = ((char*) ptr->buf) + 1; + void* addr_typedef = ((char*) ptr->buf_typedef) + 1; +} + +// ============================================================================= +// # union incomplete type +// ============================================================================= + +// expected-note@+1 8{{consider providing a complete definition for 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy')}} +union IncompleteUnionTy; // expected-note 8{{consider providing a complete definition for 'union IncompleteUnionTy'}} +typedef union IncompleteUnionTy IncompleteUnion_ty; + +void consume_struct_IncompleteUnionTy(union IncompleteUnionTy* buf); + +struct CBBufUnionTyPos { + int count; + union IncompleteUnionTy* __counted_by_or_null(count) buf ; // OK expected-note 8{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} + IncompleteUnion_ty *__counted_by_or_null(count) buf_typedef; // OK expected-note 8{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} +}; + +void use_CBBufUnionTyPos(struct CBBufUnionTyPos* ptr) { + struct CBBufUnionTyPos explicit_desig_init = { + .count = 0, + // expected-error@+1{{cannot initialize 'CBBufUnionTyPos::buf' with '__counted_by_or_null' attributed type 'union IncompleteUnionTy * __counted_by_or_null(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}} + .buf = 0x0, + // expected-error@+1{{cannot initialize 'CBBufUnionTyPos::buf_typedef' with '__counted_by_or_null' attributed type 'IncompleteUnion_ty * __counted_by_or_null(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}} + .buf_typedef = 0x0 + }; + + // Assignment + // expected-error@+1{{cannot assign to 'CBBufUnionTyPos::buf' with '__counted_by_or_null' attributed type 'union IncompleteUnionTy * __counted_by_or_null(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}} + explicit_desig_init.buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufUnionTyPos::buf_typedef' with '__counted_by_or_null' attributed type 'IncompleteUnion_ty * __counted_by_or_null(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}} + explicit_desig_init.buf_typedef = 0x0; + // expected-error@+1{{cannot assign to 'CBBufUnionTyPos::buf' with '__counted_by_or_null' attributed type 'union IncompleteUnionTy * __counted_by_or_null(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}} + ptr->buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufUnionTyPos::buf_typedef' with '__counted_by_or_null' attributed type 'IncompleteUnion_ty * __counted_by_or_null(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}} + ptr->buf_typedef = 0x0; + + // Use + // expected-error@+2{{cannot use 'ptr->buf' with '__counted_by_or_null' attributed type 'union IncompleteUnionTy * __counted_by_or_null(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}} + void* addr = + ((char*) ptr->buf ) + 1; + // expected-error@+2{{cannot use 'ptr->buf_typedef' with '__counted_by_or_null' attributed type 'IncompleteUnion_ty * __counted_by_or_null(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}} + void* addr_typedef = + ((char*) ptr->buf_typedef ) + 1; + + // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by_or_null' attributed type 'union IncompleteUnionTy * __counted_by_or_null(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}} + consume_struct_IncompleteUnionTy(ptr->buf); + // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by_or_null' attributed type 'IncompleteUnion_ty * __counted_by_or_null(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}} + consume_struct_IncompleteUnionTy(ptr->buf_typedef); + + // expected-error@+1 2{{cannot use 'ptr->buf' with '__counted_by_or_null' attributed type 'union IncompleteUnionTy * __counted_by_or_null(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}} + ptr->buf[0] = ptr->buf[1]; + // expected-error@+1 2{{cannot use 'ptr->buf_typedef' with '__counted_by_or_null' attributed type 'IncompleteUnion_ty * __counted_by_or_null(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}} + ptr->buf_typedef[0] = ptr->buf_typedef[1]; +} + +struct CBBufUnionTyPos global_explicit_desig_init_union_type_pos = { + .count = 0, + // expected-error@+1{{cannot initialize 'CBBufUnionTyPos::buf' with '__counted_by_or_null' attributed type 'union IncompleteUnionTy * __counted_by_or_null(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}} + .buf = 0x0, + // expected-error@+1{{cannot initialize 'CBBufUnionTyPos::buf_typedef' with '__counted_by_or_null' attributed type 'IncompleteUnion_ty * __counted_by_or_null(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}} + .buf_typedef = 0x0 +}; + +// Defining the type makes `CBBufUnionTyPos` fields usable +union IncompleteUnionTy { + int field; +}; + +void use_CBBufUnionTyPos_completed(struct CBBufUnionTyPos* ptr) { + ptr->buf = 0x0; + ptr->buf_typedef = 0x0; + void* addr = ((char*) ptr->buf) + 1; + void* addr_typedef = ((char*) ptr->buf_typedef) + 1; +} + +// ============================================================================= +// # enum incomplete type +// ============================================================================= + +// expected-note@+1 8{{consider providing a complete definition for 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy')}} +enum IncompleteEnumTy; // expected-note 8{{consider providing a complete definition for 'enum IncompleteEnumTy'}} +typedef enum IncompleteEnumTy IncompleteEnum_ty; + +void consume_struct_IncompleteEnumTy(enum IncompleteEnumTy* buf); + +struct CBBufEnumTyPos { + int count; + enum IncompleteEnumTy* __counted_by_or_null(count) buf ; // OK expected-note 8{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} + IncompleteEnum_ty *__counted_by_or_null(count) buf_typedef; // OK expected-note 8{{consider using '__sized_by_or_null' instead of '__counted_by_or_null'}} +}; + +void use_CBBufEnumTyPos(struct CBBufEnumTyPos* ptr) { + struct CBBufEnumTyPos explicit_desig_init = { + .count = 0, + // expected-error@+1{{cannot initialize 'CBBufEnumTyPos::buf' with '__counted_by_or_null' attributed type 'enum IncompleteEnumTy * __counted_by_or_null(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}} + .buf = 0x0, + // expected-error@+1{{cannot initialize 'CBBufEnumTyPos::buf_typedef' with '__counted_by_or_null' attributed type 'IncompleteEnum_ty * __counted_by_or_null(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}} + .buf_typedef = 0x0 + }; + + // Assignment + // expected-error@+1{{cannot assign to 'CBBufEnumTyPos::buf' with '__counted_by_or_null' attributed type 'enum IncompleteEnumTy * __counted_by_or_null(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}} + explicit_desig_init.buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufEnumTyPos::buf_typedef' with '__counted_by_or_null' attributed type 'IncompleteEnum_ty * __counted_by_or_null(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}} + explicit_desig_init.buf_typedef = 0x0; + // expected-error@+1{{cannot assign to 'CBBufEnumTyPos::buf' with '__counted_by_or_null' attributed type 'enum IncompleteEnumTy * __counted_by_or_null(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}} + ptr->buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufEnumTyPos::buf_typedef' with '__counted_by_or_null' attributed type 'IncompleteEnum_ty * __counted_by_or_null(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}} + ptr->buf_typedef = 0x0; + + // Use + // expected-error@+2{{cannot use 'ptr->buf' with '__counted_by_or_null' attributed type 'enum IncompleteEnumTy * __counted_by_or_null(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}} + void* addr = + ((char*) ptr->buf ) + 1; + // expected-error@+2{{cannot use 'ptr->buf_typedef' with '__counted_by_or_null' attributed type 'IncompleteEnum_ty * __counted_by_or_null(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}} + void* addr_typedef = + ((char*) ptr->buf_typedef ) + 1; + + // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by_or_null' attributed type 'enum IncompleteEnumTy * __counted_by_or_null(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}} + consume_struct_IncompleteEnumTy(ptr->buf); + // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by_or_null' attributed type 'IncompleteEnum_ty * __counted_by_or_null(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}} + consume_struct_IncompleteEnumTy(ptr->buf_typedef); + + // expected-error@+1 2{{cannot use 'ptr->buf' with '__counted_by_or_null' attributed type 'enum IncompleteEnumTy * __counted_by_or_null(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}} + ptr->buf[0] = ptr->buf[1]; + // expected-error@+1 2{{cannot use 'ptr->buf_typedef' with '__counted_by_or_null' attributed type 'IncompleteEnum_ty * __counted_by_or_null(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}} + ptr->buf_typedef[0] = ptr->buf_typedef[1]; +} + +struct CBBufEnumTyPos global_explicit_desig_init_enum_type_pos = { + .count = 0, + // expected-error@+1{{cannot initialize 'CBBufEnumTyPos::buf' with '__counted_by_or_null' attributed type 'enum IncompleteEnumTy * __counted_by_or_null(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}} + .buf = 0x0, + // expected-error@+1{{cannot initialize 'CBBufEnumTyPos::buf_typedef' with '__counted_by_or_null' attributed type 'IncompleteEnum_ty * __counted_by_or_null(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}} + .buf_typedef = 0x0 +}; + +// Defining the type makes `CBBufEnumTyPos` fields usable +enum IncompleteEnumTy { + ONE, + TWO +}; + +void use_CBBufEnumTyPos_completed(struct CBBufEnumTyPos* ptr) { + ptr->buf = 0x0; + ptr->buf_typedef = 0x0; + void* addr = ((char*) ptr->buf) + 1; + void* addr_typedef = ((char*) ptr->buf_typedef) + 1; +} + +// Make a complete enum by providing an underlying type +enum CompleteEnumTy : unsigned; +typedef enum CompleteEnumTy CompleteEnum_ty; +struct CBBufEnumTyPos2 { + int count; + enum CompleteEnumTy* __counted_by_or_null(count) buf; + CompleteEnum_ty *__counted_by_or_null(count) buf_typedef; +}; + +void use_CBBufEnumTyPos2(struct CBBufEnumTyPos2* ptr) { + struct CBBufEnumTyPos2 explicit_desig_init = { + .count = 0, + .buf = 0x0, // OK + .buf_typedef = 0x0 // OK + }; +} + +// Make a complete enum by providing a concrete declaration +enum CompleteEnumTy2 { + VALUE_ONE, + VALUE_TWO +}; +typedef enum CompleteEnumTy2 CompleteEnum_ty2; +struct CBBufEnumTyPos3 { + int count; + enum CompleteEnumTy2* __counted_by_or_null(count) buf; + CompleteEnum_ty2 *__counted_by_or_null(count) buf_typedef; +}; + +void use_CBBufEnumTyPos3(struct CBBufEnumTyPos3* ptr) { + struct CBBufEnumTyPos3 explicit_desig_init = { + .count = 0, + .buf = 0x0, // OK + .buf_typedef = 0x0 // OK + }; +} + + +// ============================================================================= +// # Array of __counted_by_or_null pointers +// ============================================================================= + +struct IncompleteTy3; + +struct CBBufFAMofCountedByPtrs { + int size; + // TODO: This is misleading. The attribute is written in the type position + // but clang currently doesn't treat it like that and it gets treated as + // an attribute on the array, rather than on the element type. + // expected-error@+1{{'counted_by_or_null' only applies to pointers; did you mean to use 'counted_by'?}} + struct IncompleteTy3* __counted_by_or_null(size) arr[]; +}; + +void arr_of_counted_by_ptr(struct CBBufFAMofCountedByPtrs* ptr) { + // TODO: Should be disallowed once parsing attributes in the type position + // works. + ptr->arr[0] = 0x0; + void* addr = ((char*) ptr->arr[0]) + 1; +} diff --git a/clang/test/Sema/attr-counted-by-or-null-struct-ptrs.c b/clang/test/Sema/attr-counted-by-or-null-struct-ptrs.c index 708bb727ce09d..0bb09059c97f9 100644 --- a/clang/test/Sema/attr-counted-by-or-null-struct-ptrs.c +++ b/clang/test/Sema/attr-counted-by-or-null-struct-ptrs.c @@ -22,14 +22,12 @@ struct on_member_pointer_complete_ty { struct on_member_pointer_incomplete_ty { int count; - // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'struct size_unknown' is an incomplete type}} - struct size_unknown * buf __counted_by_or_null(count); + struct size_unknown * buf __counted_by_or_null(count); // ok }; struct on_member_pointer_const_incomplete_ty { int count; - // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'const struct size_unknown' is an incomplete type}} - const struct size_unknown * buf __counted_by_or_null(count); + const struct size_unknown * buf __counted_by_or_null(count); // ok }; struct on_member_pointer_void_ty { @@ -116,14 +114,12 @@ struct on_member_pointer_complete_ty_ty_pos { struct on_member_pointer_incomplete_ty_ty_pos { int count; - // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'struct size_unknown' is an incomplete type}} - struct size_unknown * __counted_by_or_null(count) buf; + struct size_unknown * __counted_by_or_null(count) buf; // ok }; struct on_member_pointer_const_incomplete_ty_ty_pos { int count; - // expected-error@+1{{'counted_by_or_null' cannot be applied to a pointer with pointee of unknown size because 'const struct size_unknown' is an incomplete type}} - const struct size_unknown * __counted_by_or_null(count) buf; + const struct size_unknown * __counted_by_or_null(count) buf; // ok }; struct on_member_pointer_void_ty_ty_pos { diff --git a/clang/test/Sema/attr-counted-by-struct-ptrs-completable-incomplete-pointee.c b/clang/test/Sema/attr-counted-by-struct-ptrs-completable-incomplete-pointee.c new file mode 100644 index 0000000000000..d28a2086b51b8 --- /dev/null +++ b/clang/test/Sema/attr-counted-by-struct-ptrs-completable-incomplete-pointee.c @@ -0,0 +1,630 @@ +// RUN: %clang_cc1 -fsyntax-only -verify %s +// RUN: %clang_cc1 -fexperimental-late-parse-attributes -fsyntax-only -verify %s + +#define __counted_by(f) __attribute__((counted_by(f))) + +// ============================================================================= +// # Struct incomplete type with attribute in the decl position +// ============================================================================= + +// Note: This could be considered misleading. The typedef isn't actually on this +// line. Also note the discrepancy in diagnostic count (27 vs 51) is due to +// the pointer arithmetic on incomplete pointee type diagnostic always using +// diagnostic text that refers to the underlying forward decl, even when the +// typedef is used. +// expected-note@+3 27{{consider providing a complete definition for 'Incomplete_t' (aka 'struct IncompleteTy')}} +// The 'forward declaration' notes come from 'arithmetic on a pointer to an incomplete type' errors +// expected-note@+1 24{{forward declaration of 'struct IncompleteTy'}} +struct IncompleteTy; // expected-note 27{{consider providing a complete definition for 'struct IncompleteTy'}} + +typedef struct IncompleteTy Incomplete_t; + +struct CBBufDeclPos { + int count; + struct IncompleteTy* buf __counted_by(count); // OK expected-note 27{{consider using '__sized_by' instead of '__counted_by'}} + Incomplete_t* buf_typedef __counted_by(count); // OK expected-note 27{{consider using '__sized_by' instead of '__counted_by'}} +}; + +void consume_struct_IncompleteTy(struct IncompleteTy* buf); + +int idx(void); + + + +void test_CBBufDeclPos(struct CBBufDeclPos* ptr) { + // =========================================================================== + // ## Local variable initialization + // =========================================================================== + struct CBBufDeclPos explicit_desig_init = { + .count = 0, + // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + .buf = 0x0, + // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + .buf_typedef = 0x0 + }; + // Variable is not currently marked as invalid so uses of the variable allows + // diagnostics to fire. + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + explicit_desig_init.buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + explicit_desig_init.buf_typedef = 0x0; + // expected-error@+1{{cannot use 'explicit_desig_init.buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + void *tmp = explicit_desig_init.buf; + // expected-error@+1{{cannot use 'explicit_desig_init.buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + void *tmp2 = explicit_desig_init.buf_typedef; + + struct CBBufDeclPos partial_explicit_desig_init = { + .count = 0, + // .buf and .buf_typedef are implicit zero initialized + // expected-error@+2{{cannot implicitly initialize 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + // expected-error@+1{{cannot implicitly initialize 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + }; + + struct CBBufDeclPos implicit_full_init = { + 0 + // expected-error@+2{{cannot implicitly initialize 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + // expected-error@+1{{cannot implicitly initialize 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + }; + // Variable is not currently marked as invalid so uses of the variable allows + // diagnostics to fire. + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + implicit_full_init.buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + implicit_full_init.buf_typedef = 0x0; + // expected-error@+1{{cannot use 'implicit_full_init.buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + void* tmp3 = implicit_full_init.buf; + // expected-error@+1{{cannot use 'implicit_full_init.buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + void* tmp4 = implicit_full_init.buf_typedef; + + struct CBBufDeclPos explicit_non_desig_init = { + 0, + // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + 0x0, + // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + 0x0 + }; + + + + + // =========================================================================== + // ## Assignment to fields + // =========================================================================== + struct CBBufDeclPos uninit; + uninit.count = 0; + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + uninit.buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + uninit.buf_typedef = 0x0; + ptr->count = 0; + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + ptr->buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + ptr->buf_typedef = 0x0; + + + // =========================================================================== + // ## Make sure modifying the fields through other assignment operators is not + // allowed + // =========================================================================== + uninit.buf++; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + ++uninit.buf; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + uninit.buf += 1; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + uninit.buf_typedef++; // // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + ++uninit.buf_typedef; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + uninit.buf_typedef -= 1; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + + uninit.buf--; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + --uninit.buf; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + uninit.buf -= 1; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + uninit.buf_typedef--; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + --uninit.buf_typedef; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + uninit.buf_typedef -= 1; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + + ptr->buf++; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + ++ptr->buf; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + ptr->buf += 1; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + ptr->buf--; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + --ptr->buf; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + ptr->buf -= 1; // expected-error{{arithmetic on a pointer to an incomplete type 'struct IncompleteTy'}} + + ptr->buf_typedef++; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + ++ptr->buf_typedef; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + ptr->buf_typedef += 1; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + ptr->buf_typedef--; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + --ptr->buf_typedef; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + ptr->buf_typedef -= 1; // expected-error{{arithmetic on a pointer to an incomplete type 'Incomplete_t' (aka 'struct IncompleteTy')}} + + // =========================================================================== + // ## Use of fields in expressions + // =========================================================================== + // expected-error@+2{{cannot use 'uninit.buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + void* addr = + ((char*) uninit.buf ) + 1; + // expected-error@+2{{cannot use 'uninit.buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + void* addr_typedef = + ((char*) uninit.buf_typedef ) + 1; + // expected-error@+2{{cannot use 'ptr->buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + void* addr_ptr = + ((char*) ptr->buf ) + 1; + // expected-error@+2{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + void* addr_ptr_typedef = + ((char*) ptr->buf_typedef ) + 1; + + + // =========================================================================== + // ## Take address of fields + // =========================================================================== + // TODO: This should be forbidden, not because of the incomplete pointee type + // but because in the -fbounds-safety language model the address of a + // `counted_by` pointer cannot be taken to avoid it being possible to modify + // the `counted_by` pointer through another pointer. Whether or not this + // should be forbidden when `-fbounds-safety` is off is TBD. + // + // The incomplete pointee type isn't actually a problem here for + // `-fbounds-safety` because taking the address of a pointer returns a pointer + // that have the bounds of a single `void*`, so bounds checks on the resulting + // pointer don't need to know `sizeof(struct IncompleteTy)` but instead + // `sizeof(struct IncompleteTy* buf __counted_by(count))` which is just the + // size of a pointer. + void* take_addr = &uninit.buf; + void* take_addr_typedef = &uninit.buf_typedef; + void* take_addr_ptr = &ptr->buf; + void* take_addr_ptr_typedef = &ptr->buf_typedef; + + // expected-error@+1{{cannot use 'uninit.buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + struct IncompleteTy* addr_elt_zero = &uninit.buf[0]; + // expected-error@+1{{cannot use 'uninit.buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + struct IncompleteTy* addr_elt_idx = &uninit.buf[idx()]; + + // expected-error@+1{{cannot use 'uninit.buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + struct IncompleteTy* addr_elt_zero_typedef = &uninit.buf_typedef[0]; + // expected-error@+1{{cannot use 'uninit.buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + struct IncompleteTy* addr_elt_idx_typedef = &uninit.buf_typedef[idx()]; + + // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + struct IncompleteTy* addr_elt_zero_ptr = &ptr->buf[0]; + // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + struct IncompleteTy* addr_elt_idx_ptr = &ptr->buf[idx()]; + // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + struct IncompleteTy* addr_elt_zero_ptr_typedef = &ptr->buf_typedef[0]; + // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + struct IncompleteTy* addr_elt_idx_ptr_typedef = &ptr->buf_typedef[idx()]; + + + // =========================================================================== + // ## Use fields as call arguments + // =========================================================================== + // expected-error@+1{{cannot use 'uninit.buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + consume_struct_IncompleteTy(uninit.buf); + // expected-error@+1{{cannot use 'uninit.buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + consume_struct_IncompleteTy(uninit.buf_typedef); + // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + consume_struct_IncompleteTy(ptr->buf); + // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + consume_struct_IncompleteTy(ptr->buf_typedef); + + // =========================================================================== + // ## Use [] operator on fields + // =========================================================================== + // expected-error@+1 2{{cannot use 'uninit.buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + uninit.buf[0] = uninit.buf[1]; + // expected-error@+1 2{{cannot use 'uninit.buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + uninit.buf_typedef[0] = uninit.buf_typedef[1]; + // expected-error@+1 2{{cannot use 'ptr->buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + ptr->buf[0] = ptr->buf[1]; + // expected-error@+1 2{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + ptr->buf_typedef[0] = ptr->buf_typedef[1]; +} + + +// ============================================================================= +// ## Global initialization +// ============================================================================= + +struct CBBufDeclPos global_explicit_desig_init = { + .count = 0, + // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + .buf = 0x0, + // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + .buf_typedef = 0x0 +}; + +void use_global_explicit_desig_init(void) { + // Variable isn't marked as invalid so diagnostics still fire + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + global_explicit_desig_init.buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + global_explicit_desig_init.buf_typedef = 0x0; +} + +struct CBBufDeclPos global_partial_explicit_desig_init = { + .count = 0, + // .buf and .buf_typedef are implicit zero initialized + // expected-error@+2{{cannot implicitly initialize 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + // expected-error@+1{{cannot implicitly initialize 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} +}; + +struct CBBufDeclPos global_implicit_full_init = { + 0 + // expected-error@+2{{cannot implicitly initialize 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + // expected-error@+1{{cannot implicitly initialize 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} +}; + +struct CBBufDeclPos global_explicit_non_desig_init = { + 0, + // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf' with '__counted_by' attributed type 'struct IncompleteTy * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'struct IncompleteTy' is incomplete}} + 0x0, + // expected-error@+1{{cannot initialize 'CBBufDeclPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_t * __counted_by(count)' (aka 'struct IncompleteTy *') because the pointee type 'Incomplete_t' (aka 'struct IncompleteTy') is incomplete}} + 0x0 +}; + +extern struct CBBufDeclPos global_declaration; // OK + +// TODO: These tentative definitions are implicitly empty initialized to zero. +// This should generate an error diagnostic but currently doesn't. There should +// be a carve out to allow `__counted_by(0)` which is the only constant count +// version of the attribute where it is valid to assign NULL. +struct CBBufDeclPos global_tentative_defn; +static struct CBBufDeclPos global_tentative_defn2; + +// ============================================================================= +// ## Completing the definition of the type allows use of CBBufDeclPos fields +// ============================================================================= +struct IncompleteTy { + int field; +}; + +void test_CBBufDeclPos_completed(struct CBBufDeclPos* ptr) { + // Initialization is ok + struct CBBufDeclPos explicit_desig_init = { + .count = 0, + .buf = 0x0, + .buf_typedef = 0x0 + }; + + struct CBBufDeclPos partial_explicit_desig_init = { + .count = 0, + // .buf and .buf_typedef are implicit zero initialized + }; + + struct CBBufDeclPos implicit_full_init = {0}; + + struct CBBufDeclPos explicit_non_desig_init = { + 0, + 0x0, + 0x0 + }; + + // Assignment to fields is ok + ptr->buf = 0x0; + ptr->buf_typedef = 0x0; + + // Use of fields in expressions is ok + void* tmp = ptr->buf; + void* tmp2 = ptr->buf_typedef; + + // Take address of fields is ok + void* take_addr_ptr = &ptr->buf; + void* take_addr_ptr_typedef = &ptr->buf_typedef; + + struct IncompleteTy* addr_elt_zero_ptr = &ptr->buf[0]; + struct IncompleteTy* addr_elt_idx_ptr = &ptr->buf[idx()]; + struct IncompleteTy* addr_elt_zero_ptr_typedef = &ptr->buf_typedef[0]; + struct IncompleteTy* addr_elt_idx_ptr_typedef = &ptr->buf_typedef[idx()]; + + // As call arguments is ok + consume_struct_IncompleteTy(ptr->buf); + consume_struct_IncompleteTy(ptr->buf_typedef); + + // In [] operator is ok + ptr->buf[0] = ptr->buf[1]; + ptr->buf_typedef[0] = ptr->buf_typedef[1]; +} + +// Global initialization is ok + +struct CBBufDeclPos global_explicit_desig_init_completed = { + .count = 0, + .buf = 0x0, + .buf_typedef = 0x0 +}; + +struct CBBufDeclPos global_partial_explicit_desig_init_completed = { + .count = 0, + // .buf and .buf_typedef are implicit zero initialized +}; + +struct CBBufDeclPos global_implicit_full_init_completed = {0}; + +struct CBBufDeclPos global_explicit_non_desig_init_completed = { + 0, + 0x0, + 0x0 +}; + +extern struct CBBufDeclPos global_declaration; +struct CBBufDeclPos global_tentative_defn; +static struct CBBufDeclPos global_tentative_defn2; + +// ============================================================================= +// # Struct incomplete type with attribute in the pointer position +// ============================================================================= + +// expected-note@+1 8{{consider providing a complete definition for 'Incomplete_ty2' (aka 'struct IncompleteTy2')}} +struct IncompleteTy2; // expected-note 8{{consider providing a complete definition for 'struct IncompleteTy2'}} +typedef struct IncompleteTy2 Incomplete_ty2; + +void consume_struct_IncompleteTy2(struct IncompleteTy2* buf); + +struct CBBufTyPos { + int count; + struct IncompleteTy2* __counted_by(count) buf ; // OK expected-note 8{{consider using '__sized_by' instead of '__counted_by'}} + Incomplete_ty2 *__counted_by(count) buf_typedef; // OK expected-note 8{{consider using '__sized_by' instead of '__counted_by'}} +}; + +void use_CBBufTyPos(struct CBBufTyPos* ptr) { + struct CBBufTyPos explicit_desig_init = { + .count = 0, + // expected-error@+1{{cannot initialize 'CBBufTyPos::buf' with '__counted_by' attributed type 'struct IncompleteTy2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}} + .buf = 0x0, + // expected-error@+1{{cannot initialize 'CBBufTyPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_ty2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}} + .buf_typedef = 0x0 + }; + + // Assignment + // expected-error@+1{{cannot assign to 'CBBufTyPos::buf' with '__counted_by' attributed type 'struct IncompleteTy2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}} + explicit_desig_init.buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufTyPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_ty2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}} + explicit_desig_init.buf_typedef = 0x0; + // expected-error@+1{{cannot assign to 'CBBufTyPos::buf' with '__counted_by' attributed type 'struct IncompleteTy2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}} + ptr->buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufTyPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_ty2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}} + ptr->buf_typedef = 0x0; + + // Use + // expected-error@+2{{cannot use 'ptr->buf' with '__counted_by' attributed type 'struct IncompleteTy2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}} + void* addr = + ((char*) ptr->buf ) + 1; + // expected-error@+2{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'Incomplete_ty2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}} + void* addr_typedef = + ((char*) ptr->buf_typedef ) + 1; + + // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by' attributed type 'struct IncompleteTy2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}} + consume_struct_IncompleteTy2(ptr->buf); + // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'Incomplete_ty2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}} + consume_struct_IncompleteTy2(ptr->buf_typedef); + + // expected-error@+1 2{{cannot use 'ptr->buf' with '__counted_by' attributed type 'struct IncompleteTy2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}} + ptr->buf[0] = ptr->buf[1]; + // expected-error@+1 2{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'Incomplete_ty2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}} + ptr->buf_typedef[0] = ptr->buf_typedef[1]; +} + +struct CBBufTyPos global_explicit_desig_init_struct_type_pos = { + .count = 0, + // expected-error@+1{{cannot initialize 'CBBufTyPos::buf' with '__counted_by' attributed type 'struct IncompleteTy2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'struct IncompleteTy2' is incomplete}} + .buf = 0x0, + // expected-error@+1{{cannot initialize 'CBBufTyPos::buf_typedef' with '__counted_by' attributed type 'Incomplete_ty2 * __counted_by(count)' (aka 'struct IncompleteTy2 *') because the pointee type 'Incomplete_ty2' (aka 'struct IncompleteTy2') is incomplete}} + .buf_typedef = 0x0 +}; + +// Defining the type makes `CBBufTyPos` fields usable +struct IncompleteTy2 { + int field; +}; + +void use_CBBufTyPos_completed(struct CBBufTyPos* ptr) { + ptr->buf = 0x0; + ptr->buf_typedef = 0x0; + void* addr = ((char*) ptr->buf) + 1; + void* addr_typedef = ((char*) ptr->buf_typedef) + 1; +} + +// ============================================================================= +// # union incomplete type +// ============================================================================= + +// expected-note@+1 8{{consider providing a complete definition for 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy')}} +union IncompleteUnionTy; // expected-note 8{{consider providing a complete definition for 'union IncompleteUnionTy'}} +typedef union IncompleteUnionTy IncompleteUnion_ty; + +void consume_struct_IncompleteUnionTy(union IncompleteUnionTy* buf); + +struct CBBufUnionTyPos { + int count; + union IncompleteUnionTy* __counted_by(count) buf ; // OK expected-note 8{{consider using '__sized_by' instead of '__counted_by'}} + IncompleteUnion_ty *__counted_by(count) buf_typedef; // OK expected-note 8{{consider using '__sized_by' instead of '__counted_by'}} +}; + +void use_CBBufUnionTyPos(struct CBBufUnionTyPos* ptr) { + struct CBBufUnionTyPos explicit_desig_init = { + .count = 0, + // expected-error@+1{{cannot initialize 'CBBufUnionTyPos::buf' with '__counted_by' attributed type 'union IncompleteUnionTy * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}} + .buf = 0x0, + // expected-error@+1{{cannot initialize 'CBBufUnionTyPos::buf_typedef' with '__counted_by' attributed type 'IncompleteUnion_ty * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}} + .buf_typedef = 0x0 + }; + + // Assignment + // expected-error@+1{{cannot assign to 'CBBufUnionTyPos::buf' with '__counted_by' attributed type 'union IncompleteUnionTy * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}} + explicit_desig_init.buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufUnionTyPos::buf_typedef' with '__counted_by' attributed type 'IncompleteUnion_ty * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}} + explicit_desig_init.buf_typedef = 0x0; + // expected-error@+1{{cannot assign to 'CBBufUnionTyPos::buf' with '__counted_by' attributed type 'union IncompleteUnionTy * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}} + ptr->buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufUnionTyPos::buf_typedef' with '__counted_by' attributed type 'IncompleteUnion_ty * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}} + ptr->buf_typedef = 0x0; + + // Use + // expected-error@+2{{cannot use 'ptr->buf' with '__counted_by' attributed type 'union IncompleteUnionTy * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}} + void* addr = + ((char*) ptr->buf ) + 1; + // expected-error@+2{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'IncompleteUnion_ty * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}} + void* addr_typedef = + ((char*) ptr->buf_typedef ) + 1; + + // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by' attributed type 'union IncompleteUnionTy * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}} + consume_struct_IncompleteUnionTy(ptr->buf); + // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'IncompleteUnion_ty * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}} + consume_struct_IncompleteUnionTy(ptr->buf_typedef); + + // expected-error@+1 2{{cannot use 'ptr->buf' with '__counted_by' attributed type 'union IncompleteUnionTy * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}} + ptr->buf[0] = ptr->buf[1]; + // expected-error@+1 2{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'IncompleteUnion_ty * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}} + ptr->buf_typedef[0] = ptr->buf_typedef[1]; +} + +struct CBBufUnionTyPos global_explicit_desig_init_union_type_pos = { + .count = 0, + // expected-error@+1{{cannot initialize 'CBBufUnionTyPos::buf' with '__counted_by' attributed type 'union IncompleteUnionTy * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'union IncompleteUnionTy' is incomplete}} + .buf = 0x0, + // expected-error@+1{{cannot initialize 'CBBufUnionTyPos::buf_typedef' with '__counted_by' attributed type 'IncompleteUnion_ty * __counted_by(count)' (aka 'union IncompleteUnionTy *') because the pointee type 'IncompleteUnion_ty' (aka 'union IncompleteUnionTy') is incomplete}} + .buf_typedef = 0x0 +}; + +// Defining the type makes `CBBufUnionTyPos` fields usable +union IncompleteUnionTy { + int field; +}; + +void use_CBBufUnionTyPos_completed(struct CBBufUnionTyPos* ptr) { + ptr->buf = 0x0; + ptr->buf_typedef = 0x0; + void* addr = ((char*) ptr->buf) + 1; + void* addr_typedef = ((char*) ptr->buf_typedef) + 1; +} + +// ============================================================================= +// # enum incomplete type +// ============================================================================= + +// expected-note@+1 8{{consider providing a complete definition for 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy')}} +enum IncompleteEnumTy; // expected-note 8{{consider providing a complete definition for 'enum IncompleteEnumTy'}} +typedef enum IncompleteEnumTy IncompleteEnum_ty; + +void consume_struct_IncompleteEnumTy(enum IncompleteEnumTy* buf); + +struct CBBufEnumTyPos { + int count; + enum IncompleteEnumTy* __counted_by(count) buf ; // OK expected-note 8{{consider using '__sized_by' instead of '__counted_by'}} + IncompleteEnum_ty *__counted_by(count) buf_typedef; // OK expected-note 8{{consider using '__sized_by' instead of '__counted_by'}} +}; + +void use_CBBufEnumTyPos(struct CBBufEnumTyPos* ptr) { + struct CBBufEnumTyPos explicit_desig_init = { + .count = 0, + // expected-error@+1{{cannot initialize 'CBBufEnumTyPos::buf' with '__counted_by' attributed type 'enum IncompleteEnumTy * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}} + .buf = 0x0, + // expected-error@+1{{cannot initialize 'CBBufEnumTyPos::buf_typedef' with '__counted_by' attributed type 'IncompleteEnum_ty * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}} + .buf_typedef = 0x0 + }; + + // Assignment + // expected-error@+1{{cannot assign to 'CBBufEnumTyPos::buf' with '__counted_by' attributed type 'enum IncompleteEnumTy * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}} + explicit_desig_init.buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufEnumTyPos::buf_typedef' with '__counted_by' attributed type 'IncompleteEnum_ty * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}} + explicit_desig_init.buf_typedef = 0x0; + // expected-error@+1{{cannot assign to 'CBBufEnumTyPos::buf' with '__counted_by' attributed type 'enum IncompleteEnumTy * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}} + ptr->buf = 0x0; + // expected-error@+1{{cannot assign to 'CBBufEnumTyPos::buf_typedef' with '__counted_by' attributed type 'IncompleteEnum_ty * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}} + ptr->buf_typedef = 0x0; + + // Use + // expected-error@+2{{cannot use 'ptr->buf' with '__counted_by' attributed type 'enum IncompleteEnumTy * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}} + void* addr = + ((char*) ptr->buf ) + 1; + // expected-error@+2{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'IncompleteEnum_ty * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}} + void* addr_typedef = + ((char*) ptr->buf_typedef ) + 1; + + // expected-error@+1{{cannot use 'ptr->buf' with '__counted_by' attributed type 'enum IncompleteEnumTy * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}} + consume_struct_IncompleteEnumTy(ptr->buf); + // expected-error@+1{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'IncompleteEnum_ty * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}} + consume_struct_IncompleteEnumTy(ptr->buf_typedef); + + // expected-error@+1 2{{cannot use 'ptr->buf' with '__counted_by' attributed type 'enum IncompleteEnumTy * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}} + ptr->buf[0] = ptr->buf[1]; + // expected-error@+1 2{{cannot use 'ptr->buf_typedef' with '__counted_by' attributed type 'IncompleteEnum_ty * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}} + ptr->buf_typedef[0] = ptr->buf_typedef[1]; +} + +struct CBBufEnumTyPos global_explicit_desig_init_enum_type_pos = { + .count = 0, + // expected-error@+1{{cannot initialize 'CBBufEnumTyPos::buf' with '__counted_by' attributed type 'enum IncompleteEnumTy * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'enum IncompleteEnumTy' is incomplete}} + .buf = 0x0, + // expected-error@+1{{cannot initialize 'CBBufEnumTyPos::buf_typedef' with '__counted_by' attributed type 'IncompleteEnum_ty * __counted_by(count)' (aka 'enum IncompleteEnumTy *') because the pointee type 'IncompleteEnum_ty' (aka 'enum IncompleteEnumTy') is incomplete}} + .buf_typedef = 0x0 +}; + +// Defining the type makes `CBBufEnumTyPos` fields usable +enum IncompleteEnumTy { + ONE, + TWO +}; + +void use_CBBufEnumTyPos_completed(struct CBBufEnumTyPos* ptr) { + ptr->buf = 0x0; + ptr->buf_typedef = 0x0; + void* addr = ((char*) ptr->buf) + 1; + void* addr_typedef = ((char*) ptr->buf_typedef) + 1; +} + +// Make a complete enum by providing an underlying type +enum CompleteEnumTy : unsigned; +typedef enum CompleteEnumTy CompleteEnum_ty; +struct CBBufEnumTyPos2 { + int count; + enum CompleteEnumTy* __counted_by(count) buf; + CompleteEnum_ty *__counted_by(count) buf_typedef; +}; + +void use_CBBufEnumTyPos2(struct CBBufEnumTyPos2* ptr) { + struct CBBufEnumTyPos2 explicit_desig_init = { + .count = 0, + .buf = 0x0, // OK + .buf_typedef = 0x0 // OK + }; +} + +// Make a complete enum by providing a concrete declaration +enum CompleteEnumTy2 { + VALUE_ONE, + VALUE_TWO +}; +typedef enum CompleteEnumTy2 CompleteEnum_ty2; +struct CBBufEnumTyPos3 { + int count; + enum CompleteEnumTy2* __counted_by(count) buf; + CompleteEnum_ty2 *__counted_by(count) buf_typedef; +}; + +void use_CBBufEnumTyPos3(struct CBBufEnumTyPos3* ptr) { + struct CBBufEnumTyPos3 explicit_desig_init = { + .count = 0, + .buf = 0x0, // OK + .buf_typedef = 0x0 // OK + }; +} + + +// ============================================================================= +// # Array of __counted_by pointers +// ============================================================================= + +struct IncompleteTy3; + +struct CBBufFAMofCountedByPtrs { + int size; + // TODO: This is misleading. The attribute is written in the type position + // but clang currently doesn't treat it like that and it gets treated as + // an attribute on the array, rather than on the element type. + struct IncompleteTy3* __counted_by(size) arr[]; +}; + +void arr_of_counted_by_ptr(struct CBBufFAMofCountedByPtrs* ptr) { + // TODO: Should be disallowed once parsing attributes in the type position + // works. + ptr->arr[0] = 0x0; + void* addr = ((char*) ptr->arr[0]) + 1; +} diff --git a/clang/test/Sema/attr-counted-by-struct-ptrs.c b/clang/test/Sema/attr-counted-by-struct-ptrs.c index 321d6aafbeba2..c05d18262e2b7 100644 --- a/clang/test/Sema/attr-counted-by-struct-ptrs.c +++ b/clang/test/Sema/attr-counted-by-struct-ptrs.c @@ -21,14 +21,12 @@ struct on_member_pointer_complete_ty { struct on_member_pointer_incomplete_ty { int count; - // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct size_unknown' is an incomplete type}} - struct size_unknown * buf __counted_by(count); + struct size_unknown * buf __counted_by(count); // ok }; struct on_member_pointer_const_incomplete_ty { int count; - // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'const struct size_unknown' is an incomplete type}} - const struct size_unknown * buf __counted_by(count); + const struct size_unknown * buf __counted_by(count); // ok }; struct on_member_pointer_void_ty { @@ -115,14 +113,12 @@ struct on_member_pointer_complete_ty_ty_pos { struct on_member_pointer_incomplete_ty_ty_pos { int count; - // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct size_unknown' is an incomplete type}} - struct size_unknown * __counted_by(count) buf; + struct size_unknown * __counted_by(count) buf; // ok }; struct on_member_pointer_const_incomplete_ty_ty_pos { int count; - // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'const struct size_unknown' is an incomplete type}} - const struct size_unknown * __counted_by(count) buf; + const struct size_unknown * __counted_by(count) buf; // ok }; struct on_member_pointer_void_ty_ty_pos { diff --git a/clang/test/Sema/attr-counted-by-vla.c b/clang/test/Sema/attr-counted-by-vla.c index 35737c03f3222..5b1b4833dce7d 100644 --- a/clang/test/Sema/attr-counted-by-vla.c +++ b/clang/test/Sema/attr-counted-by-vla.c @@ -98,8 +98,7 @@ struct array_of_ints_count { struct not_a_fam { int count; - // expected-error@+1{{'counted_by' cannot be applied to a pointer with pointee of unknown size because 'struct bar' is an incomplete type}} - struct bar *non_fam __counted_by(count); + struct bar *non_fam __counted_by(count); // ok }; struct not_a_c99_fam {