From 61ecf41dfb78d79e80e10b78b7fabca7bbea0269 Mon Sep 17 00:00:00 2001 From: ziruichen Date: Mon, 15 Dec 2025 10:33:55 +0800 Subject: [PATCH 1/3] [ownership] bugfix for IDA26J. when ptr wrapped in paren expr, ownership analysis give false positice result. --- clang/lib/Analysis/BSC/BSCOwnership.cpp | 4 +-- .../paren_expr_around_pointer.cbs | 29 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 clang/test/BSC/Positive/Ownership/paren_expr_around_pointer/paren_expr_around_pointer.cbs diff --git a/clang/lib/Analysis/BSC/BSCOwnership.cpp b/clang/lib/Analysis/BSC/BSCOwnership.cpp index 3948ee249242..c317fdab3989 100644 --- a/clang/lib/Analysis/BSC/BSCOwnership.cpp +++ b/clang/lib/Analysis/BSC/BSCOwnership.cpp @@ -1951,7 +1951,7 @@ void TransferFunctions::VisitCStyleCastExpr(CStyleCastExpr *CSCE) { // @code // (void * owned)s // @endcode - if (const DeclRefExpr *DRE = dyn_cast(ICE->getSubExpr())) { + if (const DeclRefExpr *DRE = dyn_cast(ICE->getSubExpr()->IgnoreParens())) { const VarDecl *VD = dyn_cast(DRE->getDecl()); if (stat.OPSStatus.count(VD)) { SmallVector diags = @@ -1968,7 +1968,7 @@ void TransferFunctions::VisitCStyleCastExpr(CStyleCastExpr *CSCE) { // (void * owned)s->p // (void * owned)s.p // @endcode - if (const MemberExpr *ME = dyn_cast(ICE->getSubExpr())) { + if (const MemberExpr *ME = dyn_cast(ICE->getSubExpr()->IgnoreParens())) { auto memberField = getMemberFullField(ME); if (const DeclRefExpr *DRE = dyn_cast(memberField.first)) { SmallVector diags = diff --git a/clang/test/BSC/Positive/Ownership/paren_expr_around_pointer/paren_expr_around_pointer.cbs b/clang/test/BSC/Positive/Ownership/paren_expr_around_pointer/paren_expr_around_pointer.cbs new file mode 100644 index 000000000000..d6b15ac5dd79 --- /dev/null +++ b/clang/test/BSC/Positive/Ownership/paren_expr_around_pointer/paren_expr_around_pointer.cbs @@ -0,0 +1,29 @@ +// RUN: %clang %s -o %t.output +// RUN: %t.output +// expected-no-diagnostics + +T* owned safe_malloc(T value) { + T * p = (T *) malloc( sizeof(T) ); + *p = value; + return (T* owned)p; +} + +void safe_free(T* owned p) { + free( (T*)p ); +} + +safe int foo(int *borrow x) { return *x; } +typedef struct S { + int *owned p; +} S; + +int main(void) { + int *owned ptr = safe_malloc(0); + int x = foo(&mut * ptr); + safe_free((void *owned)(ptr)); + S s = {.p = safe_malloc(1)}; + S *owned pp = safe_malloc(s); + safe_free((void *owned)(pp->p)); + safe_free((void *owned)(pp)); + return 0; +} -- Gitee From 1b99b52ef9d1de536782dce56ab191b6de3fdf80 Mon Sep 17 00:00:00 2001 From: ziruichen Date: Mon, 15 Dec 2025 14:50:11 +0800 Subject: [PATCH 2/3] [ownership] fix false positive ownership analysis outcome when freeing an nested pointer. --- clang/lib/Analysis/BSC/BSCOwnership.cpp | 52 ++++++++++++++++++- .../safe_free_nested_owned_pointer.cbs | 25 +++++++++ .../safe_free_nested_owned_pointer2.cbs | 21 ++++++++ .../safe_free_nested_pointer.cbs | 26 ++++++++++ 4 files changed, 123 insertions(+), 1 deletion(-) create mode 100644 clang/test/BSC/Negative/Ownership/Owned/safe_free_nested_owned_pointer/safe_free_nested_owned_pointer.cbs create mode 100644 clang/test/BSC/Negative/Ownership/Owned/safe_free_nested_owned_pointer2/safe_free_nested_owned_pointer2.cbs create mode 100644 clang/test/BSC/Positive/Ownership/safe_free_nested_pointer/safe_free_nested_pointer.cbs diff --git a/clang/lib/Analysis/BSC/BSCOwnership.cpp b/clang/lib/Analysis/BSC/BSCOwnership.cpp index c317fdab3989..7c3e97a4ebc7 100644 --- a/clang/lib/Analysis/BSC/BSCOwnership.cpp +++ b/clang/lib/Analysis/BSC/BSCOwnership.cpp @@ -1614,7 +1614,9 @@ Ownership::OwnershipStatus::checkCastBOP(const VarDecl *VD, const SourceLocation &Loc) { SmallVector diags; - if (has(VD, Ownership::Status::Moved) || is(VD, Ownership::Status::Moved)) { + // AllMoved is OK - it means all sub-fields are freed, so we can free the variable itself + if ((has(VD, Ownership::Status::Moved) || is(VD, Ownership::Status::Moved)) && + !is(VD, Ownership::Status::AllMoved)) { diags.push_back(OwnershipDiagInfo(Loc, OwnershipDiagKind::InvalidCastMoved, VD->getNameAsString())); } @@ -1700,6 +1702,31 @@ SmallVector Ownership::OwnershipStatus::checkCastField( } } + if (BOPStatus.count(VD)) { + if (!BOPOwnedOwnedFields[VD].count(fullFieldName) && diags.empty()) { + diags.push_back(OwnershipDiagInfo( + Loc, OwnershipDiagKind::InvalidCastMoved, + moveAsterisksToFront(VD->getNameAsString() + "." + fullFieldName))); + } + // Check for deeper-level owned fields (e.g., when freeing **, check if *** exists) + auto ownedPrefixStrs = findPrefixStrings(BOPOwnedOwnedFields[VD], fullFieldName + "*"); + if (!ownedPrefixStrs.empty() && diags.empty()) { + diags.push_back(OwnershipDiagInfo( + Loc, OwnershipDiagKind::InvalidCastFieldOwned, + moveAsterisksToFront(VD->getNameAsString() + "." + fullFieldName), + concatFields(VD, ownedPrefixStrs))); + } + BOPOwnedOwnedFields[VD].erase(fullFieldName); + // Remove deeper-level fields + for (auto str : ownedPrefixStrs) { + BOPOwnedOwnedFields[VD].erase(str); + } + if (BOPOwnedOwnedFields[VD].empty()) { + resetAll(VD); + set(VD, Ownership::Status::AllMoved); + } + } + return diags; } @@ -1977,6 +2004,29 @@ void TransferFunctions::VisitCStyleCastExpr(CStyleCastExpr *CSCE) { reporter.addDiags(diags); } } + // @code + // (void * owned)*outer + // (void * owned)**ultraout + // @endcode + if (const UnaryOperator *UO = dyn_cast(ICE->getSubExpr()->IgnoreParens())) { + // Count dereferences and find the base DeclRefExpr + string fieldName; + const Expr *E = UO; + while (const UnaryOperator *U = dyn_cast(E)) { + if (U->getOpcode() == UO_Deref) { + fieldName += "*"; + E = U->getSubExpr()->IgnoreParenImpCasts(); + } else { + break; + } + } + if (const DeclRefExpr *DRE = dyn_cast(E->IgnoreParenImpCasts())) { + const VarDecl *VD = dyn_cast(DRE->getDecl()); + SmallVector diags = + stat.checkCastField(VD, DRE->getLocation(), fieldName); + reporter.addDiags(diags); + } + } } } else { Visit(CSCE->getSubExpr()); diff --git a/clang/test/BSC/Negative/Ownership/Owned/safe_free_nested_owned_pointer/safe_free_nested_owned_pointer.cbs b/clang/test/BSC/Negative/Ownership/Owned/safe_free_nested_owned_pointer/safe_free_nested_owned_pointer.cbs new file mode 100644 index 000000000000..eeea9553b58c --- /dev/null +++ b/clang/test/BSC/Negative/Ownership/Owned/safe_free_nested_owned_pointer/safe_free_nested_owned_pointer.cbs @@ -0,0 +1,25 @@ +// RUN: %clang_cc1 -verify %s + +void*malloc(unsigned long); +void free(void *); +T* owned safe_malloc(T value) { + T * p = (T *) malloc( sizeof(T) ); + *p = value; + return (T* owned)p; +} + +void safe_free(T* owned p) { + free( (T*)p ); +} + +void test_double_pointer_ok() { + int* owned inner = safe_malloc(1); + int* owned * owned outer = safe_malloc(inner); + int* owned * owned * owned ultraout = safe_malloc(outer); + safe_free((void *owned)**ultraout); + safe_free((void *owned)ultraout); //expected-error {{invalid cast to `void * owned` of not all moved value: `ultraout`, *ultraout is owned}} +} +int main(){ + test_double_pointer_ok(); + return 0; +} \ No newline at end of file diff --git a/clang/test/BSC/Negative/Ownership/Owned/safe_free_nested_owned_pointer2/safe_free_nested_owned_pointer2.cbs b/clang/test/BSC/Negative/Ownership/Owned/safe_free_nested_owned_pointer2/safe_free_nested_owned_pointer2.cbs new file mode 100644 index 000000000000..046b2f1adb43 --- /dev/null +++ b/clang/test/BSC/Negative/Ownership/Owned/safe_free_nested_owned_pointer2/safe_free_nested_owned_pointer2.cbs @@ -0,0 +1,21 @@ +// RUN: %clang %s -o %t.output +// RUN: %t.output +// expected-no-diagnostics + +T* owned safe_malloc(T value) { + T * p = (T *) malloc( sizeof(T) ); + *p = value; + return (T* owned)p; +} + +void safe_free(T* owned p) { + free( (T*)p ); +} + +int main() { + int * owned p = safe_malloc(2); + int * owned * owned pp = safe_malloc(p); + safe_free((void * owned) *pp); + safe_free((void * owned) pp); + return 0; +} diff --git a/clang/test/BSC/Positive/Ownership/safe_free_nested_pointer/safe_free_nested_pointer.cbs b/clang/test/BSC/Positive/Ownership/safe_free_nested_pointer/safe_free_nested_pointer.cbs new file mode 100644 index 000000000000..455ebad28c84 --- /dev/null +++ b/clang/test/BSC/Positive/Ownership/safe_free_nested_pointer/safe_free_nested_pointer.cbs @@ -0,0 +1,26 @@ +// RUN: %clang %s -o %t.output +// RUN: %t.output +// expected-no-diagnostics + +T* owned safe_malloc(T value) { + T * p = (T *) malloc( sizeof(T) ); + *p = value; + return (T* owned)p; +} + +void safe_free(T* owned p) { + free( (T*)p ); +} + +void test_double_pointer_ok() { + int* owned inner = safe_malloc(1); + int* owned * owned outer = safe_malloc(inner); + int* owned * owned * owned ultraout = safe_malloc(outer); + safe_free((void *owned)**ultraout); + safe_free((void *owned)*ultraout); + safe_free((void *owned)ultraout); +} +int main(){ + test_double_pointer_ok(); + return 0; +} \ No newline at end of file -- Gitee From c706c0d041d179a0035725f2b2be71f751e83b5e Mon Sep 17 00:00:00 2001 From: ziruichen Date: Tue, 16 Dec 2025 11:32:28 +0800 Subject: [PATCH 3/3] [ownership] reporting error on adding owned qulifier on unsupportted types. --- .../clang/Basic/BSC/DiagnosticBSCGroups.td | 6 +- .../clang/Basic/BSC/DiagnosticBSCSemaKinds.td | 5 +- clang/include/clang/Sema/Sema.h | 1 + clang/lib/Sema/BSC/SemaBSCOwnership.cpp | 41 ++++ clang/lib/Sema/SemaDecl.cpp | 41 ++-- ...ber_function_this_parameter_definition.cbs | 8 +- .../tag-name/generic-struct-tag-name.cbs | 1 + .../OwnedStruct/tag-name/tag-name.cbs | 6 +- .../Borrow/borrow_deref/borrow_deref.cbs | 24 +-- .../generic_with_owned_args1.cbs | 6 +- .../owned_CStyleCast/owned_CStyleCast.cbs | 14 +- .../Ownership/Owned/owned_arr/owned_arr.cbs | 8 +- .../Owned/owned_ast_check/owned_ast_check.cbs | 12 +- .../Owned/owned_funcPtr/owned_funcPtr.cbs | 6 +- .../owned_global_err/owned_global_err.cbs | 4 +- .../owned_global_pointer.cbs | 8 +- .../owned_global_typedef.cbs | 4 +- .../Owned/owned_impCast/owned_impCast.cbs | 6 +- .../Ownership/Owned/owned_init/owned_init.cbs | 30 ++- .../owned_memberExpr/owned_memberExpr.cbs | 10 +- .../owned_qualifier_non_pointer.cbs | 83 ++++++++ .../Owned/owned_struct/owned_struct.cbs | 3 +- .../Owned/owned_struct/owned_struct_cbs.h | 4 +- .../owned_temporary_funCall1.cbs | 2 +- .../owned_temporary_funCall3.cbs | 4 +- .../Owned/owned_union_err/owned_union_err.cbs | 13 +- .../return_qualified_type.cbs | 12 +- .../endscope-and-block/endscope-and-block.cbs | 13 +- .../generic_with_owned_args2.cbs | 7 +- .../multi-level-pointer.cbs | 33 ++-- .../multi-level-pointer2.cbs} | 10 +- .../owned-struct-private-member-init.cbs | 10 +- .../param-or-var2/param-or-var2.cbs} | 8 +- .../rewrite_bsc_owned1/rewrite_bsc_owned1.cbs | 24 +++ .../rewrite_bsc_owned3/rewrite_bsc_owned3.cbs | 90 +++++++++ .../borrow_check_function_decl.cbs | 20 +- .../trait_qualifiers_this_param.cbs | 53 ++++++ .../rewrite_bsc_owned1/rewrite_bsc_owned1.cbs | 51 ----- .../rewrite_bsc_owned3/rewrite_bsc_owned3.cbs | 180 ------------------ .../trait_qualifiers_this_param.cbs | 116 ----------- 40 files changed, 451 insertions(+), 526 deletions(-) create mode 100644 clang/test/BSC/Negative/Ownership/Owned/owned_qualifier_non_pointer/owned_qualifier_non_pointer.cbs rename clang/test/BSC/{Positive/Ownership => Negative/Ownership/RuleCheck}/generic_with_owned_args2/generic_with_owned_args2.cbs (72%) rename clang/test/BSC/{Positive/Ownership/RuleCheck/multi-level-pointer/multi-level-pointer.cbs => Negative/Ownership/RuleCheck/multi-level-pointer2/multi-level-pointer2.cbs} (74%) rename clang/test/BSC/{Positive/OwnedStruct/Access => Negative/Ownership/RuleCheck}/owned-struct-private-member-init.cbs (54%) rename clang/test/BSC/{Positive/Ownership/RuleCheck/param-or-var/param-or-var.cbs => Negative/Ownership/RuleCheck/param-or-var2/param-or-var2.cbs} (51%) create mode 100644 clang/test/BSC/Negative/Ownership/RuleCheck/rewrite_bsc_owned1/rewrite_bsc_owned1.cbs create mode 100644 clang/test/BSC/Negative/Ownership/RuleCheck/rewrite_bsc_owned3/rewrite_bsc_owned3.cbs create mode 100644 clang/test/BSC/Negative/Trait/trait_qualifiers_this_param/trait_qualifiers_this_param.cbs delete mode 100644 clang/test/BSC/Positive/Driver/rewrite-bsc/Ownership/rewrite_bsc_owned1/rewrite_bsc_owned1.cbs delete mode 100644 clang/test/BSC/Positive/Driver/rewrite-bsc/Ownership/rewrite_bsc_owned3/rewrite_bsc_owned3.cbs delete mode 100644 clang/test/BSC/Positive/Trait/r3/trait_qualifiers_this_param/trait_qualifiers_this_param.cbs diff --git a/clang/include/clang/Basic/BSC/DiagnosticBSCGroups.td b/clang/include/clang/Basic/BSC/DiagnosticBSCGroups.td index e20ae4c594f5..0ac3f7604ad4 100644 --- a/clang/include/clang/Basic/BSC/DiagnosticBSCGroups.td +++ b/clang/include/clang/Basic/BSC/DiagnosticBSCGroups.td @@ -28,13 +28,15 @@ def CastOwned : DiagGroup<"cast-owned", [CastMovedOwned]>; def CheckMemoryLeak : DiagGroup<"check-memory-leak">; def DestructOwnedStruct : DiagGroup<"destruct-owned-struct">; def PartiallyMovedStruct : DiagGroup<"partially-moved-struct">; -def BSCOwnership : DiagGroup<"bsc-ownership", +def OwnedQualifierType : DiagGroup<"owned-qualifier-type">; +def BSCOwnership : DiagGroup<"bsc-ownership", [UseOwned, AssignOwned, CastOwned, CheckMemoryLeak, PartiallyMovedStruct, - DestructOwnedStruct]>; + DestructOwnedStruct, + OwnedQualifierType]>; def AssignBorrowed : DiagGroup<"assign-borrowed">; def MoveBorrowed : DiagGroup<"move-borrowed">; diff --git a/clang/include/clang/Basic/BSC/DiagnosticBSCSemaKinds.td b/clang/include/clang/Basic/BSC/DiagnosticBSCSemaKinds.td index 2fa516bc0c1d..acb102a20f64 100644 --- a/clang/include/clang/Basic/BSC/DiagnosticBSCSemaKinds.td +++ b/clang/include/clang/Basic/BSC/DiagnosticBSCSemaKinds.td @@ -4,8 +4,6 @@ def err_no_instance_member : Error< "no instance member named %0 in %1; did you mean to use '::' instead of '%select{.|->}2'?">; def err_cvrqualified_member_type_unsupported : Error< "type of member function is wrong, CVR qualified type is unsupported, but found '%0'">; -def err_cvrqualified_this_type_unsupported : Error< - "owned type requires a pointer, '%0' is invalid">; def err_this_type_unsupported : Error< "type of parameter 'this' is wrong, expected 'This*' or 'This' or '%0*' or '%0', but found '%1'">; def err_incompatible_pointer_cast : Error< @@ -78,6 +76,9 @@ def err_borrow_qualcheck_compare : Error< def err_typecheck_borrow_func : Error<"no borrow qualified type found in the function parameters, the return type is not allowed to be borrow qualified">; def err_typecheck_borrow_subscript : Error<"subscript of borrow pointer is not allowed">; def err_owned_and_borrow_conflict : Error<"cannot combine 'owned' and 'borrow' qualifiers on the same type">; +def err_owned_qualifier_non_pointer : Error< + "type of %1 cannot be qualified by '%0'">, + InGroup; // BSC trait warnings and errors. diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index d8de64a915e3..1bc7a8ccd0a1 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -12417,6 +12417,7 @@ public: bool CheckOwnedFunctionPointerType(QualType LHSType, Expr* RHSExpr); void CheckOwnedOrIndirectOwnedType(SourceLocation ErrLoc, QualType T, StringRef Env); bool CheckOwnedDecl(SourceLocation ErrLoc, QualType T); + void CheckOwnedQualifierOnNonPointerType(const DeclSpec &DS, QualType T); bool CheckTemporaryVarMemoryLeak(Expr* E); void BSCDataflowAnalysis(const Decl *D, bool EnableOwnershipCheck = true, bool EnableNullabilityCheck = true); diff --git a/clang/lib/Sema/BSC/SemaBSCOwnership.cpp b/clang/lib/Sema/BSC/SemaBSCOwnership.cpp index 1f918160fccb..51fc16a5c441 100644 --- a/clang/lib/Sema/BSC/SemaBSCOwnership.cpp +++ b/clang/lib/Sema/BSC/SemaBSCOwnership.cpp @@ -48,6 +48,47 @@ bool Sema::CheckOwnedDecl(SourceLocation ErrLoc, QualType T) { return true; } +// Check if 'owned' qualifier is applied to a non-pointer type +void Sema::CheckOwnedQualifierOnNonPointerType(const DeclSpec &DS, QualType T) { + if (!getLangOpts().BSC || getLangOpts().DisableOwnershipCheck) + return; + + // Check if owned was explicitly written + if (!DS.getOwnedSpecLoc().isValid()) + return; + + QualType BaseType = T; + // Strip all pointer levels to get to the base type that was in the DeclSpec + while (const PointerType *PT = BaseType->getAs()) { + BaseType = PT->getPointeeType(); + } + // Also strip arrays + if (const ArrayType *AT = BaseType->getAsArrayTypeUnsafe()) { + BaseType = AT->getElementType(); + } + + // Now check if the base type has owned on non-pointer + if (BaseType.isOwnedQualified() && !BaseType->isPointerType() && + !BaseType->isOwnedStructureType() && !BaseType->isOwnedTemplateSpecializationType()) { + QualType UnqualType = BaseType; + UnqualType.removeLocalFastQualifiers(Qualifiers::Owned); + Diag(DS.getOwnedSpecLoc(), diag::err_owned_qualifier_non_pointer) + << "owned" << UnqualType; + } else if (!T->isPointerType() && !T->isOwnedStructureType() && + !T->isOwnedTemplateSpecializationType()) { + // Also check the complete type for cases like "int owned x" + QualType UnqualType = T; + if (const ArrayType *AT = UnqualType->getAsArrayTypeUnsafe()) + UnqualType = AT->getElementType(); + if (const PointerType *PT = UnqualType->getAs()) + UnqualType = PT->getPointeeType(); + if (UnqualType.isOwnedQualified()) + UnqualType.removeLocalFastQualifiers(Qualifiers::Owned); + Diag(DS.getOwnedSpecLoc(), diag::err_owned_qualifier_non_pointer) + << "owned" << UnqualType; + } +} + bool Sema::CheckOwnedQualTypeCStyleCast(QualType LHSType, QualType RHSType) { QualType RHSCanType = RHSType.getCanonicalType(); QualType LHSCanType = LHSType.getCanonicalType(); diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index c7bfeb708742..197e0bc83525 100755 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -6783,6 +6783,11 @@ Sema::ActOnTypedefDeclarator(Scope* S, Declarator& D, DeclContext* DC, Diag(D.getDeclSpec().getConstexprSpecLoc(), diag::err_invalid_constexpr) << 1 << static_cast(D.getDeclSpec().getConstexprSpecifier()); +#if ENABLE_BSC + // Check if 'owned' qualifier is applied to a non-pointer type (typedefs) + CheckOwnedQualifierOnNonPointerType(D.getDeclSpec(), TInfo->getType()); +#endif + if (D.getName().Kind != UnqualifiedIdKind::IK_Identifier) { if (D.getName().Kind == UnqualifiedIdKind::IK_DeductionGuideName) Diag(D.getName().StartLocation, @@ -7538,6 +7543,11 @@ NamedDecl *Sema::ActOnVariableDeclarator( bool IsLocalExternDecl = SC == SC_Extern && adjustContextForLocalExternDecl(DC); +#if ENABLE_BSC + // Check if 'owned' qualifier is applied to a non-pointer type (variables) + CheckOwnedQualifierOnNonPointerType(D.getDeclSpec(), R); +#endif + if (SCSpec == DeclSpec::SCS_mutable) { // mutable can only appear on non-static class members, so it's always // an error here @@ -9765,6 +9775,12 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC, if (R.getCanonicalType()->castAs()->getCmseNSCallAttr()) Diag(D.getIdentifierLoc(), diag::err_function_decl_cmse_ns_call); +#if ENABLE_BSC + // Check if 'owned' qualifier is applied to a non-pointer return type + QualType ReturnType = R->getAs()->getReturnType(); + CheckOwnedQualifierOnNonPointerType(D.getDeclSpec(), ReturnType); +#endif + SmallVector TemplateParamLists; llvm::append_range(TemplateParamLists, TemplateParamListsRef); if (TemplateParameterList *Invented = D.getInventedTemplateParameterList()) { @@ -14702,22 +14718,6 @@ void Sema::CheckFunctionOrTemplateParamDeclarator(Scope *S, Declarator &D) { } } -static bool CheckThisParamQualifiers(QualType thisParamT) { - if (!thisParamT->isPointerType()) { - // not allow This owned/borrow - // borrow not pointer is alredy checked in the Sema::BuildQualifiedType - if (thisParamT.isOwnedQualified()) { - bool IsOwnedStruct = thisParamT->isOwnedStructureType() || - thisParamT->isOwnedTemplateSpecializationType(); - // only owned struct ok - if (!(IsOwnedStruct && thisParamT.getQualifiers().hasOnlyOwned())) { - return false; - } - } - } - return true; -} - /// ActOnParamDeclarator - Called from Parser::ParseFunctionDeclarator() /// to introduce parameters into function prototype scope. Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D @@ -14770,6 +14770,8 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D // Check for redeclaration of parameters, e.g. int foo(int x, int x); IdentifierInfo *II = D.getIdentifier(); #if ENABLE_BSC + // Check if 'owned' qualifier is applied to a non-pointer type (parameters) + CheckOwnedQualifierOnNonPointerType(DS, parmDeclType); if (getLangOpts().BSC && DS.getSafeZoneSpecifier() != SZ_None) { Diag(DS.getSafeZoneSpecifierLoc(), diag::err_safe_zone_decl) << DS.getSafeZoneSpecifier(); @@ -14792,11 +14794,6 @@ Decl *Sema::ActOnParamDeclarator(Scope *S, Declarator &D << ExtendedType.getAsString(); D.setInvalidType(true); } - if (!CheckThisParamQualifiers(parmDeclType)) { - Diag(D.getBeginLoc(), diag::err_cvrqualified_this_type_unsupported) - << parmDeclType.getAsString(); - D.setInvalidType(true); - } auto ThisTypePtr = parmDeclType.getTypePtrOrNull(); if (ThisTypePtr) { if (ThisTypePtr->isPointerType()) { @@ -18135,6 +18132,8 @@ FieldDecl *Sema::HandleField(Scope *S, RecordDecl *Record, SourceLocation DeclSt CheckOwnedOrIndirectOwnedType(D.getIdentifierLoc(), T, "union field"); CheckBorrowOrIndirectBorrowType(D.getIdentifierLoc(), T, "union field"); } + // Check if 'owned' qualifier is applied to a non-pointer type (fields) + CheckOwnedQualifierOnNonPointerType(D.getDeclSpec(), T); #endif // Check to see if this name was declared as a member previously diff --git a/clang/test/BSC/Negative/Method/This/this_as_first_parameter/member_function_this_parameter_definition/member_function_this_parameter_definition.cbs b/clang/test/BSC/Negative/Method/This/this_as_first_parameter/member_function_this_parameter_definition/member_function_this_parameter_definition.cbs index 8690d8c982b3..f4f4b8267958 100644 --- a/clang/test/BSC/Negative/Method/This/this_as_first_parameter/member_function_this_parameter_definition/member_function_this_parameter_definition.cbs +++ b/clang/test/BSC/Negative/Method/This/this_as_first_parameter/member_function_this_parameter_definition/member_function_this_parameter_definition.cbs @@ -23,10 +23,10 @@ int struct Foo::getC(const This borrow this) { // expected-error {{borrow type r int struct Foo::getC_2(const struct Foo borrow this) { // expected-error {{borrow type requires a pointer or reference ('struct Foo' is invalid)}} return 0; } -int struct Foo::getD(This owned this) { // expected-error {{owned type requires a pointer, 'owned This' is invalid}} +int struct Foo::getD(This owned this) { // expected-error {{type of 'This' cannot be qualified by 'owned'}} return 0; } -int struct Foo::getD_2(struct Foo owned this) { // expected-error {{owned type requires a pointer, 'owned struct Foo' is invalid}} +int struct Foo::getD_2(struct Foo owned this) { // expected-error {{type of 'struct Foo' cannot be qualified by 'owned'}} return 0; } @@ -45,11 +45,11 @@ int Bar::getB_2(Bar this) { // ok return 0; } -int Bar::getC(This owned this) { // expected-error {{owned type requires a pointer, 'owned This' is invalid}} +int Bar::getC(This owned this) { // expected-error {{type of 'This' cannot be qualified by 'owned'}} return 0; } // expected-warning@+1 {{duplicate 'owned' declaration specifier}} -int Bar::getC_2(Bar owned this) { +int Bar::getC_2(Bar owned this) { return 0; } diff --git a/clang/test/BSC/Negative/OwnedStruct/tag-name/generic-struct-tag-name.cbs b/clang/test/BSC/Negative/OwnedStruct/tag-name/generic-struct-tag-name.cbs index fea1c69c27f1..6ea6b3bb60d8 100644 --- a/clang/test/BSC/Negative/OwnedStruct/tag-name/generic-struct-tag-name.cbs +++ b/clang/test/BSC/Negative/OwnedStruct/tag-name/generic-struct-tag-name.cbs @@ -7,6 +7,7 @@ owned struct D { owned struct D b; // expected-error {{must ignore 'owned struct' tag before struct name}} // expected-error@-1 {{type of global variable cannot qualified by 'owned'}} int owned struct D::f() { // expected-error {{must ignore 'owned struct' tag before struct name}} + // expected-error@-1 {{type of 'int' cannot be qualified by 'owned'}} return 0; } struct F; diff --git a/clang/test/BSC/Negative/OwnedStruct/tag-name/tag-name.cbs b/clang/test/BSC/Negative/OwnedStruct/tag-name/tag-name.cbs index 9b0b5d916801..cf7103145c9b 100644 --- a/clang/test/BSC/Negative/OwnedStruct/tag-name/tag-name.cbs +++ b/clang/test/BSC/Negative/OwnedStruct/tag-name/tag-name.cbs @@ -18,7 +18,7 @@ owned struct A ff() { // expected-error {{must ignore 'owned struct' tag before return b; } -int owned struct A::f() { // expected-error {{must ignore 'owned struct' tag before struct name}} +int owned struct A::f() { // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{must ignore 'owned struct' tag before struct name}} return 0; } @@ -28,10 +28,10 @@ int A::g(owned struct A* this) { // expected-error {{must ignore 'owned struct' struct D; -owned struct D {};//// expected-error {{inconsistent tag before struct name}} +owned struct D {};// expected-error {{inconsistent tag before struct name}} int main() { owned struct A b; // expected-error {{must ignore 'owned struct' tag before struct name}} - owned struct B bb; + owned struct B bb; // expected-error {{type of 'struct B' cannot be qualified by 'owned'}} return 0; } \ No newline at end of file diff --git a/clang/test/BSC/Negative/Ownership/Borrow/borrow_deref/borrow_deref.cbs b/clang/test/BSC/Negative/Ownership/Borrow/borrow_deref/borrow_deref.cbs index 62fd4464791d..3d53d446d790 100644 --- a/clang/test/BSC/Negative/Ownership/Borrow/borrow_deref/borrow_deref.cbs +++ b/clang/test/BSC/Negative/Ownership/Borrow/borrow_deref/borrow_deref.cbs @@ -7,9 +7,9 @@ struct R { int * owned foo(int * owned a) { return a; } -int owned foo1() { - int owned a = 1; - int owned * borrow b = &mut a; +int owned foo1() { // expected-error {{type of 'int' cannot be qualified by 'owned'}} + int owned a = 1; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + int owned * borrow b = &mut a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} return *b; // expected-error {{borrow type does not allow move ownership}} } @@ -21,26 +21,26 @@ void foo2() { return; } -int owned test_use(int owned a){ +int owned test_use(int owned a){ // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{type of 'int' cannot be qualified by 'owned'}} return a; } int foo3() { - int owned a = 1; - int owned * borrow b = &mut a; - int owned c = test_use(*b); // expected-error {{borrow type does not allow move ownership}} + int owned a = 1; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + int owned * borrow b = &mut a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + int owned c = test_use(*b); // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{borrow type does not allow move ownership}} int d = (int)a; return 0; } struct S1 { - int owned * borrow a; + int owned * borrow a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} int * b; }; int foo4() { - int owned m = 1; + int owned m = 1; // expected-error {{type of 'int' cannot be qualified by 'owned'}} int n = 1; struct S1 k = {&mut m, &n}; - int owned a = *(k.a); // expected-error {{borrow type does not allow move ownership}} + int owned a = *(k.a); // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{borrow type does not allow move ownership}} int b = *(k.b); } @@ -51,8 +51,8 @@ struct S2 { int foo5() { int m = 1; int n = 1; - struct S2 owned * borrow k = &mut(struct S2 owned){&m, &n}; - struct S2 owned a = *(k); // expected-error {{borrow type does not allow move ownership}} + struct S2 owned * borrow k = &mut(struct S2 owned){&m, &n}; // expected-error {{type of 'struct S2' cannot be qualified by 'owned'}} + struct S2 owned a = *(k); // expected-error {{type of 'struct S2' cannot be qualified by 'owned'}} expected-error {{borrow type does not allow move ownership}} } diff --git a/clang/test/BSC/Negative/Ownership/Owned/generic_with_owned_args1/generic_with_owned_args1.cbs b/clang/test/BSC/Negative/Ownership/Owned/generic_with_owned_args1/generic_with_owned_args1.cbs index 0030173f932f..b656cca2d171 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/generic_with_owned_args1/generic_with_owned_args1.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/generic_with_owned_args1/generic_with_owned_args1.cbs @@ -5,15 +5,15 @@ int a = 0; -owned int* Func_1() +owned int* Func_1() // expected-error {{type of 'int' cannot be qualified by 'owned'}} { - T tmp = (owned int*)a; //expected-warning {{cast to 'owned int *' from smaller integer type 'int'}} [-Wincompatible-pointer-types-discards-qualifiers] expected-warning {{cast to 'owned int *' from smaller integer type 'int'}} [-Wincompatible-pointer-types-discards-qualifiers] + T tmp = (owned int*)a; // expected-warning {{cast to 'owned int *' from smaller integer type 'int'}} [-Wincompatible-pointer-types-discards-qualifiers] expected-warning {{cast to 'owned int *' from smaller integer type 'int'}} [-Wincompatible-pointer-types-discards-qualifiers] return tmp; } int main() { - owned int* res = Func_1(); //expected-note {{in instantiation of function template specialization 'Func_1' requested here}} + owned int* res = Func_1(); // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-note {{in instantiation of function template specialization 'Func_1' requested here}} if (*res != 0) { return 1; diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_CStyleCast/owned_CStyleCast.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_CStyleCast/owned_CStyleCast.cbs index b4845673328e..61dd4019b27a 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_CStyleCast/owned_CStyleCast.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_CStyleCast/owned_CStyleCast.cbs @@ -6,8 +6,8 @@ void test1() { int* owned p3 = (int* owned)p1; //legal void* owned p4 = (void* owned)p1; //legal float* owned p2 = (float* owned)p1; //expected-error {{incompatible owned types, cannot cast 'int *owned' to 'float *owned'}} - int owned a = 10; - float owned b = (float owned)a; //expected-error {{incompatible owned types, cannot cast 'owned int' to 'owned float'}} + int owned a = 10; //expected-error {{type of 'int' cannot be qualified by 'owned'}} + float owned b = (float owned)a; //expected-error {{type of 'float' cannot be qualified by 'owned'}} //expected-error {{incompatible owned types, cannot cast 'owned int' to 'owned float'}} void* owned p5; int* owned p6 = (int* owned)p5; //legal } @@ -27,17 +27,17 @@ void test3() { } //with const & muiti-layer pointer -void test4(int** p0, owned int* p1, int* p3) { +void test4(int** p0, owned int* p1, int* p3) { //expected-error {{type of 'int' cannot be qualified by 'owned'}} const int* owned p11 = (const int* owned)p1; - owned int* const owned * owned p22 = (owned int* const owned * owned)p0; + owned int* const owned * owned p22 = (owned int* const owned * owned)p0; //expected-error {{type of 'int' cannot be qualified by 'owned'}} int* const * owned p33 = (int* const * owned)p0; void* owned p44 = (void* owned)p3; - owned int* p55 = (owned int*)p3; + owned int* p55 = (owned int*)p3; //expected-error {{type of 'int' cannot be qualified by 'owned'}} } // illegal cases -void test5(float owned f1, float* owned f2){ - int owned a1 = (int owned)f1; //expected-error {{incompatible owned types, cannot cast 'owned float' to 'owned int'}} +void test5(float owned f1, float* owned f2){ //expected-error {{type of 'float' cannot be qualified by 'owned'}} + int owned a1 = (int owned)f1; //expected-error {{incompatible owned types, cannot cast 'owned float' to 'owned int'}} //expected-error {{type of 'int' cannot be qualified by 'owned'}} int* owned a2 = (int* owned)f2; //expected-error {{incompatible owned types, cannot cast 'float *owned' to 'int *owned'}} void* owned a4 = (void* owned)0; //expected-error {{incompatible owned types, cannot cast 'int' to 'void *owned'}} } diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_arr/owned_arr.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_arr/owned_arr.cbs index 06215ef6fef5..05f78188880a 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_arr/owned_arr.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_arr/owned_arr.cbs @@ -1,14 +1,14 @@ // RUN: %clang_cc1 -ast-dump -verify %s typedef struct A { - owned int a; + owned int a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} } SA; void test() { - owned int arr1[10]; // expected-error {{type of array cannot qualified by 'owned}} + owned int arr1[10]; // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{type of array cannot qualified by 'owned}} SA arr2[3]; // expected-error {{type of array cannot qualified by 'owned'(even indirectly), 'SA' (aka 'struct A') contains 'owned' type}} struct A arr[4]; // expected-error {{type of array cannot qualified by 'owned'(even indirectly), 'struct A' contains 'owned' type}} - owned int* arr3[2]; + owned int* arr3[2]; // expected-error {{type of 'int' cannot be qualified by 'owned'}} SA* arr4[3]; return; } @@ -19,5 +19,5 @@ void test2() { } struct B { - owned int arr1[3]; // expected-error {{type of array cannot qualified by 'owned'}} + owned int arr1[3]; // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{type of array cannot qualified by 'owned'}} }; \ No newline at end of file diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_ast_check/owned_ast_check.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_ast_check/owned_ast_check.cbs index 124539e7bba2..fe045858efea 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_ast_check/owned_ast_check.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_ast_check/owned_ast_check.cbs @@ -3,9 +3,9 @@ // RUN: | FileCheck -strict-whitespace %s struct A { - owned int a; - int owned b; - int owned * c; + owned int a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + int owned b; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + int owned * c; // expected-error {{type of 'int' cannot be qualified by 'owned'}} int* owned d; int* owned* owned e; }; @@ -17,7 +17,7 @@ struct A { // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} {{.*}}e 'int *owned *owned' void ownedTest0() { - int owned a; + int owned a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} int* owned b; int* owned * owned d; return; @@ -32,9 +32,9 @@ void ownedTest0() { // CHECK-NEXT: VarDecl 0x{{[^ ]*}} {{.*}}d 'int *owned *owned' // CHECK-NEXT: ReturnStmt 0x{{[^ ]*}} {{.*}} -int ownedTest1(owned int x, owned int* y, owned int* owned c, owned int* owned * d) { +int ownedTest1(owned int x, owned int* y, owned int* owned c, owned int* owned * d) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{type of 'int' cannot be qualified by 'owned'}} return 0; -} // expected-error {{memory leak of value: `c`}} +} // CHECK: FunctionDecl 0x{{[^ ]*}} {{.*}}ownedTest1 'int (owned int, owned int *, owned int *owned, owned int *owned *)' // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} {{.*}}x 'owned int' // CHECK-NEXT: ParmVarDecl 0x{{[^ ]*}} {{.*}}y 'owned int *' diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_funcPtr/owned_funcPtr.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_funcPtr/owned_funcPtr.cbs index 329d76adff27..43be2eabdd7b 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_funcPtr/owned_funcPtr.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_funcPtr/owned_funcPtr.cbs @@ -4,8 +4,8 @@ int myadd(int* a, int* b) { return *a + *b; } -int owned myadd2(int* a, int* b) { - int owned x = 10; +int owned myadd2(int* a, int* b) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} + int owned x = 10; // expected-error {{type of 'int' cannot be qualified by 'owned'}} return x; } @@ -24,7 +24,7 @@ void test1() { // case2: unOwned to owned void test2() { - FTP owned ftp1 = myadd; //expected-error {{incompatible owned types, cannot cast 'int (int *, int *)' to 'owned FTP' (aka 'int (*owned)(int *, int *)'}} + FTP owned ftp1 = myadd; //expected-error {{incompatible owned types, cannot cast 'int (int *, int *)' to 'owned FTP' (aka 'int (*owned)(int *, int *)')}} } // case3: inner owned check diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_global_err/owned_global_err.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_global_err/owned_global_err.cbs index 32c32c602fc1..fdd68c223ba9 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_global_err/owned_global_err.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_global_err/owned_global_err.cbs @@ -1,9 +1,9 @@ // RUN: %clang_cc1 -ast-dump -verify %s -owned int a = 10; //expected-error {{type of global variable cannot qualified by 'owned'}} +owned int a = 10; //expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{type of global variable cannot qualified by 'owned'}} typedef struct A { - owned int num; + owned int num; // expected-error {{type of 'int' cannot be qualified by 'owned'}} }SA; SA sa1 = {.num = 10}; //expected-error {{type of global variable cannot qualified by 'owned'(even indirectly), 'SA' (aka 'struct A') contains 'owned' type}} diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_global_pointer/owned_global_pointer.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_global_pointer/owned_global_pointer.cbs index e9e56f177368..ad63fdf50e03 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_global_pointer/owned_global_pointer.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_global_pointer/owned_global_pointer.cbs @@ -1,12 +1,12 @@ // RUN: %clang_cc1 -ast-dump -verify %s -int owned a; //expected-error {{type of global variable cannot qualified by 'owned'}} -owned int b; //expected-error {{type of global variable cannot qualified by 'owned'}} +int owned a; //expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{type of global variable cannot qualified by 'owned'}} +owned int b; //expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{type of global variable cannot qualified by 'owned'}} -int owned* p1; +int owned* p1; //expected-error {{type of 'int' cannot be qualified by 'owned'}} int* owned p3; //expected-error {{type of global variable cannot qualified by 'owned'}} int** owned p4; //expected-error {{type of global variable cannot qualified by 'owned'}} int* owned* p5; -owned int** p6; \ No newline at end of file +owned int** p6; // expected-error {{type of 'int' cannot be qualified by 'owned'}} \ No newline at end of file diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_global_typedef/owned_global_typedef.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_global_typedef/owned_global_typedef.cbs index 442ad95372a5..4fba0a9eda0b 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_global_typedef/owned_global_typedef.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_global_typedef/owned_global_typedef.cbs @@ -1,10 +1,10 @@ // RUN: %clang_cc1 -ast-dump -verify %s -typedef owned int ownInt; +typedef owned int ownInt; // expected-error {{type of 'int' cannot be qualified by 'owned'}} ownInt a = 10; //expected-error {{type of global variable cannot qualified by 'owned', 'ownInt' (aka 'owned int') contains 'owned' type}} typedef struct A { - owned int a; + owned int a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} }AA; AA aa; //expected-error {{type of global variable cannot qualified by 'owned'(even indirectly), 'AA' (aka 'struct A') contains 'owned' type}} diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_impCast/owned_impCast.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_impCast/owned_impCast.cbs index 92275fe367ae..99af28b803f5 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_impCast/owned_impCast.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_impCast/owned_impCast.cbs @@ -60,8 +60,8 @@ int test6_1() int test7() { short a = 0; - owned short *b = &a; //expected-error {{incompatible owned types, cannot cast 'short *' to 'owned short *'}} - owned int **c = (owned int**)&b; // expected-error {{incompatible owned types, cannot cast 'owned short **' to 'owned int **'}} + owned short *b = &a; // expected-error {{type of 'short' cannot be qualified by 'owned'}} //expected-error {{incompatible owned types, cannot cast 'short *' to 'owned short *'}} + owned int **c = (owned int**)&b; // expected-error {{type of 'int' cannot be qualified by 'owned'}} // expected-error {{incompatible owned types, cannot cast 'owned short **' to 'owned int **'}} if(**c != 0) { return 1; } @@ -79,7 +79,7 @@ void test9() { } // pointer to owned type, recursively check -void test10(owned int* p0) { +void test10(owned int* p0) {// expected-error {{type of 'int' cannot be qualified by 'owned'}} int* p1 = p0; //expected-error {{incompatible owned types, cannot cast 'owned int *' to 'int *'}} } diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_init/owned_init.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_init/owned_init.cbs index dea7ac61734e..46dc3067d162 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_init/owned_init.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_init/owned_init.cbs @@ -1,17 +1,16 @@ // RUN: %clang_cc1 -ast-dump -verify %s void test1() { - int owned a = 10; //legal - int owned a1 = 10.0f; //expected-error {{incompatible owned types, cannot cast 'float' to 'owned int'}} - int owned c = 10 + 20; //expected-error {{incompatible owned types, cannot cast 'int' to 'owned int'}} - int owned b = (int owned)10; //legal - + int owned a = 10; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + int owned a1 = 10.0f; // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{incompatible owned types, cannot cast 'float' to 'owned int'}} + int owned c = 10 + 20; /// expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{incompatible owned types, cannot cast 'int' to 'owned int'}} + int owned b = (int owned)10; // expected-error {{type of 'int' cannot be qualified by 'owned'}} int d = 10; - int owned e = d; //expected-error {{incompatible owned types, cannot cast 'int' to 'owned int'}} - int owned f = (int owned)d; //legal + int owned e = d; // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{incompatible owned types, cannot cast 'int' to 'owned int'}} + int owned f = (int owned)d; // expected-error {{type of 'int' cannot be qualified by 'owned'}} - float owned f1 = 1.0f; - char owned c1 = 'c'; + float owned f1 = 1.0f;// expected-error {{type of 'float' cannot be qualified by 'owned'}} + char owned c1 = 'c';// expected-error {{type of 'char' cannot be qualified by 'owned'}} } typedef struct A { @@ -19,18 +18,17 @@ typedef struct A { }SA; typedef struct B { - owned int num; + owned int num;// expected-error {{type of 'int' cannot be qualified by 'owned'}} }SB; void test2() { - struct A owned a1 = {.num = 10}; - SA owned a2 = {.num = 20}; - - struct B owned b1 = {.num = 10}; - SB owned b2 = {.num = 20}; + struct A owned a1 = {.num = 10}; // expected-error {{type of 'struct A' cannot be qualified by 'owned'}} + SA owned a2 = {.num = 20}; // expected-error {{type of 'SA' (aka 'struct A') cannot be qualified by 'owned'}} + struct B owned b1 = {.num = 10}; // expected-error {{type of 'struct B' cannot be qualified by 'owned'}} + SB owned b2 = {.num = 20}; // expected-error {{type of 'SB' (aka 'struct B') cannot be qualified by 'owned'}} } void test3() { int a = 10; - int* owned b = &a; //expected-error {{incompatible owned types, cannot cast 'int *' to 'int *owned'}} + int* owned b = &a; // expected-error {{incompatible owned types, cannot cast 'int *' to 'int *owned'}} } \ No newline at end of file diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_memberExpr/owned_memberExpr.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_memberExpr/owned_memberExpr.cbs index b2ee0e93585f..342c19696791 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_memberExpr/owned_memberExpr.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_memberExpr/owned_memberExpr.cbs @@ -6,17 +6,17 @@ struct Base { struct A { int b; - owned int* c; - owned struct Base base; + owned int* c; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + owned struct Base base; // expected-error {{type of 'struct Base' cannot be qualified by 'owned'}} }; -int * owned foo(owned int* a) { +int * owned foo(owned int* a) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} return (int* owned)a; } void test2() { - struct A owned a; + struct A owned a; // expected-error {{type of 'struct A' cannot be qualified by 'owned'}} int res = a.b; //unlike const, a.b's QualType is int(not owned int) int * owned res2 = foo(a.c); //a.c's QualType is owned int*(not owned int* owned) int res3 = a.base.num; -} // expected-error {{memory leak of value: `res2`}} \ No newline at end of file +} \ No newline at end of file diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_qualifier_non_pointer/owned_qualifier_non_pointer.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_qualifier_non_pointer/owned_qualifier_non_pointer.cbs new file mode 100644 index 000000000000..aefa081758ac --- /dev/null +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_qualifier_non_pointer/owned_qualifier_non_pointer.cbs @@ -0,0 +1,83 @@ +// RUN: %clang_cc1 -ast-dump -verify %s + +// Test that 'owned' qualifier can only be applied to pointer types + +struct S { + int x; +}; + +// Define an owned struct to test the exception +owned struct OwnedS { + int y; +}; + +// Define a template owned struct to test the exception +owned struct OwnedT { + T value; +}; + +void test_owned_non_pointer_types() { + // These should trigger the error: 'owned' qualifier on non-pointer primitive types + int owned a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + float owned b; // expected-error {{type of 'float' cannot be qualified by 'owned'}} + double owned c; // expected-error {{type of 'double' cannot be qualified by 'owned'}} + char owned d; // expected-error {{type of 'char' cannot be qualified by 'owned'}} + long owned e; // expected-error {{type of 'long' cannot be qualified by 'owned'}} + short owned f; // expected-error {{type of 'short' cannot be qualified by 'owned'}} + struct S owned g; // expected-error {{type of 'struct S' cannot be qualified by 'owned'}} +} + +void test_owned_valid_types() { + // These are valid: 'owned' qualifier on pointer types (no errors expected) + int * owned p1; + float * owned p2; + double * owned p3; + char * owned p4; + struct S * owned p5; + void * owned p6; + + // Using owned struct types directly (no explicit 'owned' qualifier applied) + OwnedS s1; + OwnedS * owned s2; // OK - pointer type + + // Using template owned struct types directly (no explicit 'owned' qualifier applied) + OwnedT t1; + OwnedT * owned t2; // OK - pointer type +} + +// Test in struct member declarations +struct TestStruct { + int owned member1; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + int * owned member2; // OK - pointer type + OwnedS member3; // OK - using owned struct type directly + struct S * owned member4; // OK - pointer type + OwnedT member5; // OK - using template owned struct type directly +}; + +// Test in function parameters +void test_function_params( + int owned param1, // expected-error {{type of 'int' cannot be qualified by 'owned'}} + int * owned param2, // OK - pointer type + OwnedS param3, // OK - using owned struct type directly + struct S * owned param4, // OK - pointer type + OwnedT param5 // OK - using template owned struct type directly +) {} + +// Test in function return types +int owned test_return1() { // expected-error {{type of 'int' cannot be qualified by 'owned'}} + return 0; +} + +int * owned test_return2() { // OK - pointer type + return 0; // expected-error {{incompatible owned types, cannot cast 'int' to 'int *owned'}} +} + +OwnedS test_return3() { // OK - using owned struct type directly + OwnedS s; + return s; +} + +OwnedT test_return4() { // OK - using template owned struct type directly + OwnedT t; + return t; +} diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_struct/owned_struct.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_struct/owned_struct.cbs index 6de3ef3a17cc..7de736355f2a 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_struct/owned_struct.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_struct/owned_struct.cbs @@ -1,9 +1,8 @@ // RUN: %clang_cc1 -ast-dump -verify %s -// expected-no-diagnostics #include "owned_struct_cbs.h" int main() { - struct A owned a; + struct A owned a; // expected-error {{type of 'struct A' cannot be qualified by 'owned'}} return 0; } diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_struct/owned_struct_cbs.h b/clang/test/BSC/Negative/Ownership/Owned/owned_struct/owned_struct_cbs.h index f27b7b79851b..6f8c8bb25884 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_struct/owned_struct_cbs.h +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_struct/owned_struct_cbs.h @@ -1,4 +1,4 @@ struct A { - owned int a; - owned int* b; + owned int a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + owned int* b; // expected-error {{type of 'int' cannot be qualified by 'owned'}} }; diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_temporary_funCall1/owned_temporary_funCall1.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_temporary_funCall1/owned_temporary_funCall1.cbs index 109161aaaa5b..7537729bdc6d 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_temporary_funCall1/owned_temporary_funCall1.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_temporary_funCall1/owned_temporary_funCall1.cbs @@ -52,7 +52,7 @@ typedef struct { } C; typedef struct { - int owned db; + int owned db; // expected-error {{type of 'int' cannot be qualified by 'owned'}} int db2; } D; diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_temporary_funCall3/owned_temporary_funCall3.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_temporary_funCall3/owned_temporary_funCall3.cbs index 8d9dd2b1dc44..4a28c0dff4dd 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_temporary_funCall3/owned_temporary_funCall3.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_temporary_funCall3/owned_temporary_funCall3.cbs @@ -1,9 +1,9 @@ // RUN: %clang_cc1 -verify %s int* owned func1(int* owned p) { return p; } -int owned func2(int owned a) { return a; } +int owned func2(int owned a) { return a; } // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{type of 'int' cannot be qualified by 'owned'}} int* func3(int* p) { return p; } -void test1(int* owned p, int owned a, int* p2) { +void test1(int* owned p, int owned a, int* p2) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} func1(p); // expected-error {{memory leak because temporary variable 'func1(p)' is owned or indirect owned type, please fix it}} *func1(p); // expected-error {{memory leak because temporary variable 'func1(p)' is owned or indirect owned type, please fix it}} int res1 = *func1(p); // expected-error {{memory leak because temporary variable 'func1(p)' is owned or indirect owned type, please fix it}} diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_union_err/owned_union_err.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_union_err/owned_union_err.cbs index 8ace5f000b21..092dc8410152 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_union_err/owned_union_err.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_union_err/owned_union_err.cbs @@ -1,7 +1,7 @@ // RUN: %clang_cc1 -ast-dump -verify %s union D { - owned int a; //expected-error {{type of union field cannot qualified by 'owned'}} + owned int a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{type of union field cannot qualified by 'owned'}} }; @@ -10,22 +10,21 @@ typedef union E { }EE; int main() { - owned union E e = {.a = 10}; //expected-error {{'union E' cannot be qualified by 'owned'}} - owned EE ee = {.a = 10}; //expected-error {{'EE' (aka 'union E') cannot be qualified by 'owned'}} - return 0; + owned union E e = {.a = 10}; // expected-error {{'union E' cannot be qualified by 'owned'}} expected-error {{type of 'union E' cannot be qualified by 'owned'}} + owned EE ee = {.a = 10}; // expected-error {{'EE' (aka 'union E') cannot be qualified by 'owned'}} expected-error {{type of 'EE' (aka 'union E') cannot be qualified by 'owned'}} } union A { - owned int* a; + owned int* a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} }; -typedef owned int ownedInt; +typedef owned int ownedInt; // expected-error {{type of 'int' cannot be qualified by 'owned'}} union B { ownedInt a; //expected-error {{type of union field cannot qualified by 'owned', 'ownedInt' (aka 'owned int') contains 'owned' type}} }; struct S { - owned int num; + owned int num; // expected-error {{type of 'int' cannot be qualified by 'owned'}} }; union C { diff --git a/clang/test/BSC/Negative/Ownership/Owned/return_qualified_type/return_qualified_type.cbs b/clang/test/BSC/Negative/Ownership/Owned/return_qualified_type/return_qualified_type.cbs index e7dec27edd58..84d01a71f3a6 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/return_qualified_type/return_qualified_type.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/return_qualified_type/return_qualified_type.cbs @@ -11,8 +11,8 @@ void* const test2(void* p) { //expected-error {{'const' type qualifier on retu return a; } -int owned test3(int size) { //legal - int owned a = (int owned)size; +int owned test3(int size) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} + int owned a = (int owned)size; // expected-error {{type of 'int' cannot be qualified by 'owned'}} return a; } @@ -21,14 +21,14 @@ int const test4(int size) { //expected-error {{'const' type qualifier on retur return a; } -int const owned test5(int size) { //legal - int const owned a = (int const owned)size; +int const owned test5(int size) { // expected-error {{type of 'const int' cannot be qualified by 'owned'}} + int const owned a = (int const owned)size; // expected-error {{type of 'const int' cannot be qualified by 'owned'}} return a; } -owned void* test7(void* p) { - owned void* a = (owned void*)(p); +owned void* test7(void* p) { // expected-error {{type of 'void' cannot be qualified by 'owned'}} + owned void* a = (owned void*)(p); // expected-error {{type of 'void' cannot be qualified by 'owned'}} return a; } diff --git a/clang/test/BSC/Negative/Ownership/RuleCheck/endscope-and-block/endscope-and-block.cbs b/clang/test/BSC/Negative/Ownership/RuleCheck/endscope-and-block/endscope-and-block.cbs index 81313e6f4c20..8986ac68bf0c 100644 --- a/clang/test/BSC/Negative/Ownership/RuleCheck/endscope-and-block/endscope-and-block.cbs +++ b/clang/test/BSC/Negative/Ownership/RuleCheck/endscope-and-block/endscope-and-block.cbs @@ -2,15 +2,14 @@ void func1() { int num = 1; - int owned * a; + int owned * a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} a = (owned int *)# } - void func2() { int num = 1; int * owned a; a = (int * owned)# -} // expected-error {{memory leak of value: `a`}} +} void func3(int * owned a) { { @@ -23,8 +22,8 @@ void func4(int * owned a) { int * p = (int *)a; } { - int * owned q = (int * owned)a; // expected-error {{use of moved value: `a`}} - } // expected-error {{memory leak of value: `q`}} + int * owned q = (int * owned)a; + } } void func5(int * owned a) { @@ -32,7 +31,7 @@ void func5(int * owned a) { int * p = (int *)a; { int * owned q = (int * owned)p; - } // expected-error {{memory leak of value: `q`}} + } } } @@ -42,6 +41,6 @@ void func6(int * owned a) { { int * owned q = (int * owned)p; {} - } // expected-error {{memory leak of value: `q`}} + } } } \ No newline at end of file diff --git a/clang/test/BSC/Positive/Ownership/generic_with_owned_args2/generic_with_owned_args2.cbs b/clang/test/BSC/Negative/Ownership/RuleCheck/generic_with_owned_args2/generic_with_owned_args2.cbs similarity index 72% rename from clang/test/BSC/Positive/Ownership/generic_with_owned_args2/generic_with_owned_args2.cbs rename to clang/test/BSC/Negative/Ownership/RuleCheck/generic_with_owned_args2/generic_with_owned_args2.cbs index 48241f23e3b6..a9b443370b13 100644 --- a/clang/test/BSC/Positive/Ownership/generic_with_owned_args2/generic_with_owned_args2.cbs +++ b/clang/test/BSC/Negative/Ownership/RuleCheck/generic_with_owned_args2/generic_with_owned_args2.cbs @@ -1,9 +1,8 @@ -// RUN: %clang_cc1 -ast-dump -verify %s -// expected-no-diagnostics +// RUN: %clang_cc1 -verify %s -owned T Func_1(T t) +owned T Func_1(T t) // expected-error {{type of 'T' cannot be qualified by 'owned'}} { - T owned tmp = (owned T)t; + T owned tmp = (owned T)t; // expected-error {{type of 'T' cannot be qualified by 'owned'}} return tmp; } diff --git a/clang/test/BSC/Negative/Ownership/RuleCheck/multi-level-pointer/multi-level-pointer.cbs b/clang/test/BSC/Negative/Ownership/RuleCheck/multi-level-pointer/multi-level-pointer.cbs index 042580beec50..cc0401abb5d5 100644 --- a/clang/test/BSC/Negative/Ownership/RuleCheck/multi-level-pointer/multi-level-pointer.cbs +++ b/clang/test/BSC/Negative/Ownership/RuleCheck/multi-level-pointer/multi-level-pointer.cbs @@ -2,32 +2,32 @@ void write_error_1(int * owned * owned * owned a) { ***a = 5; -} // expected-error {{memory leak of value: `a`}} expected-error {{field memory leak of value: `a`, *a, **a are leak}} +}// expected-error {{memory leak of value: `a`}} expected-error {{field memory leak of value: `a`, *a, **a are leak}} -void write_error_2(owned int * owned * owned * owned a) { - owned int * owned * owned * owned b = a; - owned int * owned * owned * owned c = a; // expected-error {{use of moved value: `a`}} -} // expected-error {{memory leak of value: `b`}} expected-error {{field memory leak of value: `b`, *b, **b are leak}} expected-error {{memory leak of value: `c`}} expected-error {{field memory leak of value: `c`, *c, **c are leak}} +void write_error_2(owned int * owned * owned * owned a) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} + owned int * owned * owned * owned b = a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + owned int * owned * owned * owned c = a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} +} -void write_error_3(owned int * owned * owned * owned a) { - owned int * owned * owned * owned b = a; - owned int * owned * owned * owned c = b; - owned int * owned * owned * owned d = b; // expected-error {{use of moved value: `b`}} -} // expected-error {{memory leak of value: `d`}} expected-error {{field memory leak of value: `d`, *d, **d are leak}} expected-error {{memory leak of value: `c`}} expected-error {{field memory leak of value: `c`, *c, **c are leak}} +void write_error_3(owned int * owned * owned * owned a) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} + owned int * owned * owned * owned b = a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + owned int * owned * owned * owned c = b; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + owned int * owned * owned * owned d = b; // expected-error {{type of 'int' cannot be qualified by 'owned'}} +} void * owned VoidPtrOwned(); void write_error_4() { void * owned c = VoidPtrOwned(); void * owned d = c; - void * owned e = c; // expected-error {{use of moved value: `c`}} -} // expected-error {{memory leak of value: `d`}} expected-error {{memory leak of value: `e`}} + void * owned e = c; +} void f4(int * owned p) { int re1; re1 = *p; return; -} // expected-error {{memory leak of value: `p`}} +} int * owned f5(int * owned p) { int re1; @@ -47,9 +47,8 @@ void f8(int * owned * owned * owned p) { int * owned * owned q; q = *p; ufree((void * owned)p); -} // expected-error {{memory leak of value: `q`}} expected-error {{field memory leak of value: `q`, *q is leak}} - +} void f9(int * owned * owned * owned p) { int * owned q = **p; - ufree((void * owned)p); // expected-error {{invalid cast to `void * owned` of not all moved value: `p`, *p is owned}} -} // expected-error {{memory leak of value: `q`}} \ No newline at end of file + ufree((void * owned)p); +} \ No newline at end of file diff --git a/clang/test/BSC/Positive/Ownership/RuleCheck/multi-level-pointer/multi-level-pointer.cbs b/clang/test/BSC/Negative/Ownership/RuleCheck/multi-level-pointer2/multi-level-pointer2.cbs similarity index 74% rename from clang/test/BSC/Positive/Ownership/RuleCheck/multi-level-pointer/multi-level-pointer.cbs rename to clang/test/BSC/Negative/Ownership/RuleCheck/multi-level-pointer2/multi-level-pointer2.cbs index 7d96d0754798..f3e79c7b7a0a 100644 --- a/clang/test/BSC/Positive/Ownership/RuleCheck/multi-level-pointer/multi-level-pointer.cbs +++ b/clang/test/BSC/Negative/Ownership/RuleCheck/multi-level-pointer2/multi-level-pointer2.cbs @@ -1,10 +1,4 @@ -// RUN: %clang_cc1 -verify %s -// expected-no-diagnostics -// RUN: %clang %s -o %t.output -// RUN: %t.output -// RUN: %clang -rewrite-bsc %s -o %t-rw.c -// RUN: %clang %t-rw.c -o %t-rw.output -// RUN: %t-rw.output +// RUN: %clang_cc1 -ast-dump -verify %s void cons(int * owned p) { int* a = (int *)p; @@ -28,7 +22,7 @@ void consumePtr(int * owned p) { return; } -void f1(int owned * p) { +void f1(int owned * p) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} return; } diff --git a/clang/test/BSC/Positive/OwnedStruct/Access/owned-struct-private-member-init.cbs b/clang/test/BSC/Negative/Ownership/RuleCheck/owned-struct-private-member-init.cbs similarity index 54% rename from clang/test/BSC/Positive/OwnedStruct/Access/owned-struct-private-member-init.cbs rename to clang/test/BSC/Negative/Ownership/RuleCheck/owned-struct-private-member-init.cbs index 442daafe654b..99af21dc45f7 100644 --- a/clang/test/BSC/Positive/OwnedStruct/Access/owned-struct-private-member-init.cbs +++ b/clang/test/BSC/Negative/Ownership/RuleCheck/owned-struct-private-member-init.cbs @@ -1,8 +1,4 @@ -// RUN: %clang %s -o %test.output -// RUN: %test.output -// RUN: %clang -rewrite-bsc %s -o %t-rw.c -// RUN: %clang %t-rw.c -o %t-rw.output -// RUN: %t-rw.output +// RUN: %clang_cc1 -ast-dump -verify %s owned struct D{ int a ; @@ -22,8 +18,8 @@ struct C{ int x; }; -owned struct C init_a(){ - owned struct C c ={2}; +owned struct C init_a(){ // expected-error {{type of 'struct C' cannot be qualified by 'owned'}} + owned struct C c ={2}; // expected-error {{type of 'struct C' cannot be qualified by 'owned'}} c.x= 2; return c; } diff --git a/clang/test/BSC/Positive/Ownership/RuleCheck/param-or-var/param-or-var.cbs b/clang/test/BSC/Negative/Ownership/RuleCheck/param-or-var2/param-or-var2.cbs similarity index 51% rename from clang/test/BSC/Positive/Ownership/RuleCheck/param-or-var/param-or-var.cbs rename to clang/test/BSC/Negative/Ownership/RuleCheck/param-or-var2/param-or-var2.cbs index 78dbc9bda7d8..365e59cc1dc5 100644 --- a/clang/test/BSC/Positive/Ownership/RuleCheck/param-or-var/param-or-var.cbs +++ b/clang/test/BSC/Negative/Ownership/RuleCheck/param-or-var2/param-or-var2.cbs @@ -1,14 +1,8 @@ // RUN: %clang_cc1 -verify %s -// expected-no-diagnostics -// RUN: %clang %s -o %t.output -// RUN: %t.output -// RUN: %clang -rewrite-bsc %s -o %t-rw.c -// RUN: %clang %t-rw.c -o %t-rw.output -// RUN: %t-rw.output void func8(int a) {} -void func9(int owned * a) {} +void func9(int owned * a) {} // expected-error {{type of 'int' cannot be qualified by 'owned'}} void func10(int * owned * a) {} diff --git a/clang/test/BSC/Negative/Ownership/RuleCheck/rewrite_bsc_owned1/rewrite_bsc_owned1.cbs b/clang/test/BSC/Negative/Ownership/RuleCheck/rewrite_bsc_owned1/rewrite_bsc_owned1.cbs new file mode 100644 index 000000000000..9bfabe574345 --- /dev/null +++ b/clang/test/BSC/Negative/Ownership/RuleCheck/rewrite_bsc_owned1/rewrite_bsc_owned1.cbs @@ -0,0 +1,24 @@ +// RUN: %clang_cc1 -ast-dump -verify %s + +struct A { + owned int a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + int owned b; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + int owned * c; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + int* owned d; + int* owned* owned e; +}; + +void ownedTest0() { + int owned a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + int* owned b; + int* owned * owned d; + return; +} + +int* owned ownedTest2(int* owned p) { + return p; +} + +int main() { + return 0; +} diff --git a/clang/test/BSC/Negative/Ownership/RuleCheck/rewrite_bsc_owned3/rewrite_bsc_owned3.cbs b/clang/test/BSC/Negative/Ownership/RuleCheck/rewrite_bsc_owned3/rewrite_bsc_owned3.cbs new file mode 100644 index 000000000000..788a3e6741af --- /dev/null +++ b/clang/test/BSC/Negative/Ownership/RuleCheck/rewrite_bsc_owned3/rewrite_bsc_owned3.cbs @@ -0,0 +1,90 @@ +// RUN: %clang_cc1 -ast-dump -verify %s + +struct A { + owned int a; // expected-error {{type of 'int' cannot be qualified by 'owned'}} +}; + +struct B { + owned int b; // expected-error {{type of 'int' cannot be qualified by 'owned'}} +}; + +struct C { + owned int** c; // expected-error {{type of 'int' cannot be qualified by 'owned'}} +}; + +struct D { struct C c; }; + +struct E { + int owned e; // expected-error {{type of 'int' cannot be qualified by 'owned'}} +}; + +struct F { + int* owned f; +}; + +struct G { + int** owned g; +}; + +struct H { + int* owned * h; +}; + +owned int (a)(); // expected-error {{type of 'int' cannot be qualified by 'owned'}} + +owned int* (b)(); // expected-error {{type of 'int' cannot be qualified by 'owned'}} + +owned int** (c)(); // expected-error {{type of 'int' cannot be qualified by 'owned'}} + + +// as return type +owned int case1() { // expected-error {{type of 'int' cannot be qualified by 'owned'}} + return 0; +} + +owned int* case2() { // expected-error {{type of 'int' cannot be qualified by 'owned'}} + return 0; +} + +owned int** case3() { // expected-error {{type of 'int' cannot be qualified by 'owned'}} + return 0; +} + +// as param type +owned int case5(owned int a) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{type of 'int' cannot be qualified by 'owned'}} +} + +int case6(owned int* a) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} + return 0; +} + +int case7(owned int** a) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} + return 0; +} + +// as local var type +owned int case8() { // expected-error {{type of 'int' cannot be qualified by 'owned'}} + owned int a = 1; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + return a; +} + +int case9() { + owned int* a = 0; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + return 0; +} + +int case10() { + owned int** a = 0; // expected-error {{type of 'int' cannot be qualified by 'owned'}} + return 0; +} + +int case11() { + (owned int*)0; // expected-warning {{expression result unused}} + return 0; +} + +int main() { + struct D * d; + return 0; +} + diff --git a/clang/test/BSC/Negative/SafeZone/borrow_check_function_decl/borrow_check_function_decl.cbs b/clang/test/BSC/Negative/SafeZone/borrow_check_function_decl/borrow_check_function_decl.cbs index a2650aae470a..bc436479c898 100644 --- a/clang/test/BSC/Negative/SafeZone/borrow_check_function_decl/borrow_check_function_decl.cbs +++ b/clang/test/BSC/Negative/SafeZone/borrow_check_function_decl/borrow_check_function_decl.cbs @@ -8,18 +8,18 @@ safe void test_1(int * p) { // expected-error {{unsafe parameter type is } // expected-error@-1 {{conflicting types for 'test_1'}} safe void test_1_0(int * owned p); // expected-note {{previous declaration is here}} -safe void test_1_0(owned int * p) { // expected-error {{unsafe parameter type is forbidden in the safe function}} +safe void test_1_0(owned int * p) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{unsafe parameter type is forbidden in the safe function}} } // expected-error@-1 {{conflicting types for 'test_1_0'}} safe void test_1_1(int * owned p); // expected-note {{previous declaration is here}} -safe void test_1_1(owned int * owned p) { // expected-error {{conflicting types for 'test_1_1'}} +safe void test_1_1(owned int * owned p) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{conflicting types for 'test_1_1'}} } safe void test_1_2(int ** owned p); // expected-note {{previous declaration is here}} -safe void test_1_2(owned int ** owned p) { // expected-error {{conflicting types for 'test_1_2'}} +safe void test_1_2(owned int ** owned p) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{conflicting types for 'test_1_2'}} } -safe void test_2(int owned p); // expected-note {{previous declaration is here}} +safe void test_2(int owned p); // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-note {{previous declaration is here}} safe void test_2(int p) { // expected-error {{conflicting types for 'test_2'}} } @@ -30,16 +30,16 @@ safe int * owned test_3(int * owned p) { // expected-error {{conflicting type } safe int * owned test_3_0(int * owned p); // expected-note {{previous declaration is here}} -safe owned int * owned test_3_0(owned int * owned p) { // expected-error {{conflicting types for 'test_3_0'}} +safe owned int * owned test_3_0(owned int * owned p) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{conflicting types for 'test_3_0'}} return p; } safe int ** owned test_3_1(int ** owned p); // expected-note {{previous declaration is here}} -safe owned int ** owned test_3_1(owned int ** owned p) { // expected-error {{conflicting types for 'test_3_1'}} +safe owned int ** owned test_3_1(owned int ** owned p) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error {{conflicting types for 'test_3_1'}} return p; } -safe int owned test_4(void); // expected-note {{previous declaration is here}} +safe int owned test_4(void); // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-note {{previous declaration is here}} safe int test_4(void) { // expected-error {{conflicting types for 'test_4'}} return 0; } @@ -85,10 +85,10 @@ unsafe void test_9_1(int * p) { // expected-error{{conflicting types for 'test } void test_9_2(int * owned p);// expected-note {{previous declaration is here}} -void test_9_2(owned int * p) {// expected-error{{conflicting types for 'test_9_2'}} +void test_9_2(owned int * p) {// expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error{{conflicting types for 'test_9_2'}} } -void test_10(int owned p);// expected-note {{previous declaration is here}} +void test_10(int owned p);// expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-note {{previous declaration is here}} void test_10(int p) { // expected-error{{conflicting types for 'test_10'}} } @@ -98,7 +98,7 @@ int * owned test_11(int *owned p) { // expected-error{{conflicting types for ' } int test_12(void);// expected-note {{previous declaration is here}} -int owned test_12(void) { // expected-error{{conflicting types for 'test_12'}} +int owned test_12(void) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} expected-error{{conflicting types for 'test_12'}} return 0; } diff --git a/clang/test/BSC/Negative/Trait/trait_qualifiers_this_param/trait_qualifiers_this_param.cbs b/clang/test/BSC/Negative/Trait/trait_qualifiers_this_param/trait_qualifiers_this_param.cbs new file mode 100644 index 000000000000..a73958a6d900 --- /dev/null +++ b/clang/test/BSC/Negative/Trait/trait_qualifiers_this_param/trait_qualifiers_this_param.cbs @@ -0,0 +1,53 @@ +// RUN: %clang_cc1 -ast-dump -verify %s + +trait F { + int foo(const This* this); + int goo(owned This* this); // expected-error {{type of 'This' cannot be qualified by 'owned'}} + int hoo(const owned This* this); // expected-error {{type of 'const This' cannot be qualified by 'owned'}} + int ioo(This* const owned this); + int joo(const This* const this); + int koo(owned This* owned this); // expected-error {{type of 'This' cannot be qualified by 'owned'}} + int loo(owned This* const this); // expected-error {{type of 'This' cannot be qualified by 'owned'}} + int moo(const This* owned this); +}; + +int int::foo(const int* this) { + return 1; +} + +int int::goo(owned int* this) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} + return 1; +} + +int int::hoo(const owned int* this) { // expected-error {{type of 'const int' cannot be qualified by 'owned'}} + return 1; +} + +int int::ioo(int* const owned this) { + int *p = (int *)this; + return 1; +} + +int int::joo(const int* const this) { + return 1; +} + +int int::koo(owned int* owned this) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} + int *p = (int *)this; + return 1; +} + +int int::loo(owned int* const this) { // expected-error {{type of 'int' cannot be qualified by 'owned'}} + return 1; +} + +int int::moo(const int* owned this) { + int *p = (int *)this; + return 1; +} + +impl trait F for int; + +int main(){ + return 0; +} diff --git a/clang/test/BSC/Positive/Driver/rewrite-bsc/Ownership/rewrite_bsc_owned1/rewrite_bsc_owned1.cbs b/clang/test/BSC/Positive/Driver/rewrite-bsc/Ownership/rewrite_bsc_owned1/rewrite_bsc_owned1.cbs deleted file mode 100644 index 1f54e7237c89..000000000000 --- a/clang/test/BSC/Positive/Driver/rewrite-bsc/Ownership/rewrite_bsc_owned1/rewrite_bsc_owned1.cbs +++ /dev/null @@ -1,51 +0,0 @@ -// RUN: %clang -rewrite-bsc %s -o %t-rw.c -// RUN: FileCheck --input-file=%t-rw.c %s -// RUN: %clang %t-rw.c -o %t-rw.output -// RUN: %t-rw.output - -struct A { - owned int a; - int owned b; - int owned * c; - int* owned d; - int* owned* owned e; -}; - -void ownedTest0() { - int owned a; - int* owned b; - int* owned * owned d; - return; -} - -int* owned ownedTest2(int* owned p) { - return p; -} - -int main() { - return 0; -} - -// CHECK:struct A { -// CHECK-NEXT: int a; -// CHECK-NEXT: int b; -// CHECK-NEXT: int *c; -// CHECK-NEXT: int * d; -// CHECK-NEXT: int * * e; -// CHECK-NEXT:}; -// CHECK-EMPTY: -// CHECK-NEXT:void ownedTest0(void) { -// CHECK-NEXT: int a; -// CHECK-NEXT: int * b; -// CHECK-NEXT: int * * d; -// CHECK-NEXT: return; -// CHECK-NEXT:} -// CHECK-EMPTY: -// CHECK-NEXT:int * ownedTest2(int * p) { -// CHECK-NEXT: return p; -// CHECK-NEXT:} -// CHECK-EMPTY: -// CHECK-NEXT:int main() { -// CHECK-NEXT: return 0; -// CHECK-NEXT:} - diff --git a/clang/test/BSC/Positive/Driver/rewrite-bsc/Ownership/rewrite_bsc_owned3/rewrite_bsc_owned3.cbs b/clang/test/BSC/Positive/Driver/rewrite-bsc/Ownership/rewrite_bsc_owned3/rewrite_bsc_owned3.cbs deleted file mode 100644 index d25bc30c3301..000000000000 --- a/clang/test/BSC/Positive/Driver/rewrite-bsc/Ownership/rewrite_bsc_owned3/rewrite_bsc_owned3.cbs +++ /dev/null @@ -1,180 +0,0 @@ -// RUN: %clang -rewrite-bsc %s -o %t-rw.c -// RUN: FileCheck --input-file=%t-rw.c %s -// RUN: %clang %t-rw.c -o %t-rw.output -// RUN: %t-rw.output - -struct A { - owned int a; -}; - -struct B { - owned int b; -}; - -struct C { - owned int** c; -}; - -struct D { struct C c; }; - -struct E { - int owned e; -}; - -struct F { - int* owned f; -}; - -struct G { - int** owned g; -}; - -struct H { - int* owned * h; -}; - -owned int (a)(); - -owned int* (b)(); - -owned int** (c)(); - - -// as return type -owned int case1() { - return 0; -} - -owned int* case2() { - return 0; -} - -owned int** case3() { - return 0; -} - -// as param type -owned int case5(owned int a) { - return a; -} - -int case6(owned int* a) { - return 0; -} - -int case7(owned int** a) { - return 0; -} - -// as local var type -owned int case8() { - owned int a = 1; - return a; -} - -int case9() { - owned int* a = 0; - return 0; -} - -int case10() { - owned int** a = 0; - return 0; -} - -int case11() { - (owned int*)0; - return 0; -} - -int main() { - struct D * d; - return 0; -} - -// CHECK: struct A { -// CHECK-NEXT: int a; -// CHECK-NEXT: }; -// CHECK-EMPTY: -// CHECK-NEXT: struct B { -// CHECK-NEXT: int b; -// CHECK-NEXT: }; -// CHECK-EMPTY: -// CHECK-NEXT: struct C { -// CHECK-NEXT: int **c; -// CHECK-NEXT: }; -// CHECK-EMPTY: -// CHECK-NEXT: struct D { -// CHECK-NEXT: struct C c; -// CHECK-NEXT: }; -// CHECK-EMPTY: -// CHECK-NEXT: struct E { -// CHECK-NEXT: int e; -// CHECK-NEXT: }; -// CHECK-EMPTY: -// CHECK-NEXT: struct F { -// CHECK-NEXT: int * f; -// CHECK-NEXT: }; -// CHECK-EMPTY: -// CHECK-NEXT: struct G { -// CHECK-NEXT: int ** g; -// CHECK-NEXT: }; -// CHECK-EMPTY: -// CHECK-NEXT: struct H { -// CHECK-NEXT: int * *h; -// CHECK-NEXT: }; -// CHECK-EMPTY: -// CHECK-NEXT: int (a)(void); -// CHECK-EMPTY: -// CHECK-NEXT: int *(b)(void); -// CHECK-EMPTY: -// CHECK-NEXT: int **(c)(void); -// CHECK-EMPTY: -// CHECK-NEXT: int case1(void) { -// CHECK-NEXT: return 0; -// CHECK-NEXT: } -// CHECK-EMPTY: -// CHECK-NEXT: int *case2(void) { -// CHECK-NEXT: return 0; -// CHECK-NEXT: } -// CHECK-EMPTY: -// CHECK-NEXT: int **case3(void) { -// CHECK-NEXT: return 0; -// CHECK-NEXT: } -// CHECK-EMPTY: -// CHECK-NEXT: int case5( int a) { -// CHECK-NEXT: return a; -// CHECK-NEXT: } -// CHECK-EMPTY: -// CHECK-NEXT: int case6( int *a) { -// CHECK-NEXT: return 0; -// CHECK-NEXT: } -// CHECK-EMPTY: -// CHECK-NEXT: int case7( int **a) { -// CHECK-NEXT: return 0; -// CHECK-NEXT: } -// CHECK-EMPTY: -// CHECK-NEXT: int case8(void) { -// CHECK-NEXT: int a = 1; -// CHECK-NEXT: return a; -// CHECK-NEXT: } -// CHECK-EMPTY: -// CHECK-NEXT: int case9(void) { -// CHECK-NEXT: int *a = 0; -// CHECK-NEXT: return 0; -// CHECK-NEXT: } -// CHECK-EMPTY: -// CHECK-NEXT: int case10(void) { -// CHECK-NEXT: int **a = 0; -// CHECK-NEXT: return 0; -// CHECK-NEXT: } -// CHECK-EMPTY: -// CHECK-NEXT: int case11(void) { -// CHECK-NEXT: ( int *)0; -// CHECK-NEXT: return 0; -// CHECK-NEXT: } -// CHECK-EMPTY: -// CHECK-NEXT: int main(void) { -// CHECK-NEXT: struct D *d; -// CHECK-NEXT: return 0; -// CHECK-NEXT: } diff --git a/clang/test/BSC/Positive/Trait/r3/trait_qualifiers_this_param/trait_qualifiers_this_param.cbs b/clang/test/BSC/Positive/Trait/r3/trait_qualifiers_this_param/trait_qualifiers_this_param.cbs deleted file mode 100644 index 2ba119439caa..000000000000 --- a/clang/test/BSC/Positive/Trait/r3/trait_qualifiers_this_param/trait_qualifiers_this_param.cbs +++ /dev/null @@ -1,116 +0,0 @@ -// RUN: %clang %s -o %t.output -// RUN: %t.output -// RUN: %clang -rewrite-bsc %s -o %t-rw.c -// RUN: FileCheck --input-file=%t-rw.c %s -// RUN: %clang %t-rw.c -o %t-rw.output -// RUN: %t-rw.output -// expected-no-diagnostics - -trait F { - int foo(const This* this); - int goo(owned This* this); - int hoo(const owned This* this); - int ioo(This* const owned this); - int joo(const This* const this); - int koo(owned This* owned this); - int loo(owned This* const this); - int moo(const This* owned this); -}; - -int int::foo(const int* this) { - return 1; -} - -int int::goo(owned int* this) { - return 1; -} - -int int::hoo(const owned int* this) { - return 1; -} - -int int::ioo(int* const owned this) { - int *p = (int *)this; - return 1; -} - -int int::joo(const int* const this) { - return 1; -} - -int int::koo(owned int* owned this) { - int *p = (int *)this; - return 1; -} - -int int::loo(owned int* const this) { - return 1; -} - -int int::moo(const int* owned this) { - int *p = (int *)this; - return 1; -} - -impl trait F for int; - -int main(){ - return 0; -} - -// CHECK: struct __Trait_F_Vtable { -// CHECK-NEXT: int (*foo)(const void *); -// CHECK-NEXT: int (*goo)( void *); -// CHECK-NEXT: int (*hoo)(const void *); -// CHECK-NEXT: int (*ioo)(void *const); -// CHECK-NEXT: int (*joo)(const void *const); -// CHECK-NEXT: int (*koo)( void *); -// CHECK-NEXT: int (*loo)( void *const); -// CHECK-NEXT: int (*moo)(const void *); -// CHECK-NEXT: }; - -// CHECK: struct __Trait_F { -// CHECK-NEXT: void *data; -// CHECK-NEXT: struct __Trait_F_Vtable *vtable; -// CHECK-NEXT: }; - -// CHECK: int int_foo(const int *this) { -// CHECK-NEXT: return 1; -// CHECK-NEXT: } - -// CHECK: int int_goo( int *this) { -// CHECK-NEXT: return 1; -// CHECK-NEXT: } - -// CHECK: int int_hoo(const int *this) { -// CHECK-NEXT: return 1; -// CHECK-NEXT: } - -// CHECK: int int_ioo(int *const this) { -// CHECK-NEXT: int *p = (int *)this; -// CHECK-NEXT: return 1; -// CHECK-NEXT: } - -// CHECK: int int_joo(const int *const this) { -// CHECK-NEXT: return 1; -// CHECK-NEXT: } - -// CHECK: int int_koo( int * this) { -// CHECK-NEXT: int *p = (int *)this; -// CHECK-NEXT: return 1; -// CHECK-NEXT: } - -// CHECK: int int_loo( int *const this) { -// CHECK-NEXT: return 1; -// CHECK-NEXT: } - -// CHECK: int int_moo(const int * this) { -// CHECK-NEXT: int *p = (int *)this; -// CHECK-NEXT: return 1; -// CHECK-NEXT: } - -// CHECK: struct __Trait_F_Vtable __int_trait_F = {.foo = (int (*)(const void *))int_foo, .goo = (int (*)( void *))int_goo, .hoo = (int (*)(const void *))int_hoo, .ioo = (int (*)(void *const))int_ioo, .joo = (int (*)(const void *const))int_joo, .koo = (int (*)( void *))int_koo, .loo = (int (*)( void *const))int_loo, .moo = (int (*)(const void *))int_moo}; - -// CHECK: int main(){ -// CHECK-NEXT: return 0; -// CHECK-NEXT: } \ No newline at end of file -- Gitee