diff --git a/clang/lib/AST/BSC/TypeBSC.cpp b/clang/lib/AST/BSC/TypeBSC.cpp index a98de8cd24feb2aae9b0cc60152435cb83b6b32f..f15cf18e1f7d3999a88a44a4f2b37900b6e73678 100644 --- a/clang/lib/AST/BSC/TypeBSC.cpp +++ b/clang/lib/AST/BSC/TypeBSC.cpp @@ -33,7 +33,7 @@ bool Type::hasOwnedFields() const { if (const auto *RecTy = dyn_cast(CanonicalType)) { return RecTy->hasOwnedFields(); } else if (const auto *PointerTy = dyn_cast(CanonicalType)) { - return PointerTy->hasOwnedFields(); + return CanonicalType.isOwnedQualified(); } return false; } @@ -156,27 +156,12 @@ void RecordType::initOwnedStatus() const { while (RecordTypeList.size() > NextToCheckIndex) { for (FieldDecl *FD : RecordTypeList[NextToCheckIndex]->getDecl()->fields()) { - QualType FieldTy = FD->getType(); - bool isOwnedStructType = - FieldTy.getCanonicalType()->isOwnedStructureType(); + QualType FieldTy = FD->getType().getCanonicalType(); + bool isOwnedStructType = FieldTy->isOwnedStructureType(); if (FieldTy.isOwnedQualified() || isOwnedStructType) { hasOwn = ownedStatus::withOwned; return; } - QualType tempQT = FieldTy; - const Type *tempT = tempQT.getTypePtr(); - while (tempT->isPointerType()) { - tempQT = tempT->getPointeeType(); - isOwnedStructType = tempQT.getCanonicalType()->isOwnedStructureType(); - if (tempQT.isOwnedQualified() && !isOwnedStructType) { - hasOwn = ownedStatus::withOwned; - return; - } else { - tempQT = tempQT.getCanonicalType(); - tempT = tempQT.getTypePtr(); - } - } - FieldTy = tempQT.getCanonicalType(); if (const auto *FieldRecTy = FieldTy->getAs()) { if (llvm::find(RecordTypeList, FieldRecTy) == RecordTypeList.end()) RecordTypeList.push_back(FieldRecTy); diff --git a/clang/lib/Analysis/BSCOwnership.cpp b/clang/lib/Analysis/BSCOwnership.cpp index 3bbe28105f2cd6ede447ae281e997761d3aabf75..84c04ceec7752ed4bee1e29b8d242c0c073ca8ea 100644 --- a/clang/lib/Analysis/BSCOwnership.cpp +++ b/clang/lib/Analysis/BSCOwnership.cpp @@ -71,7 +71,6 @@ static bool IsTrackedType(QualType type) { return true; // case 3 - // FIXME: hasOwnedFields() maybe implemented incorrect, to be confirmed later if ((type->isRecordType() && type.getTypePtr()->isOwnedStructureType()) || (type->isRecordType() && type->hasOwnedFields())) return true; diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp index 1722e14be82d0ecde5ea2e38dec67282bf13f6c7..c605201445ff4ac62a3d2fcc0525be5f894d3f0c 100644 --- a/clang/lib/Sema/SemaInit.cpp +++ b/clang/lib/Sema/SemaInit.cpp @@ -4503,7 +4503,9 @@ static void TryListInitialization(Sema &S, DestType->isOwnedTemplateSpecializationType())) { // Check explicit constructor for owned struct has private field. RecordDecl *RD = DestType->getAsRecordDecl(); - auto FD = S.getCurFunctionDecl()->getFirstDecl(); + FunctionDecl *FD = nullptr; + if (S.getCurFunctionDecl()) + FD = S.getCurFunctionDecl()->getFirstDecl(); bool IsInitedInMemberFunc = false; if (FD && isa(FD->getLexicalDeclContext())) { IsInitedInMemberFunc = diff --git a/clang/test/BSC/Negative/OwnedStruct/global-var/global-var.cbs b/clang/test/BSC/Negative/OwnedStruct/global-var/global-var.cbs new file mode 100644 index 0000000000000000000000000000000000000000..d870fde642154c6d9add00b790f214ade2197472 --- /dev/null +++ b/clang/test/BSC/Negative/OwnedStruct/global-var/global-var.cbs @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -verify %s + +owned struct S { +public: + int a; + int b; +}; + +S s1 = {}; // expected-error {{type of global variable cannot qualified by 'owned' }} +S s2 = { 2, 3 }; // expected-error {{type of global variable cannot qualified by 'owned' }} +S s3 = { .a = 1, .b = 2}; // expected-error {{type of global variable cannot qualified by 'owned' }} + +owned struct U { +public: + T a; + int* p; +}; + +U u1 = {}; // expected-error {{type of global variable cannot qualified by 'owned' }} +U u2 = { 1.5, 0 }; // expected-error {{type of global variable cannot qualified by 'owned' }} +U u3 = { 2, 0 }; // expected-error {{type of global variable cannot qualified by 'owned' }} \ No newline at end of file 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 bbf3e32db9d8f34901346e75909f89bfa186f2dd..06215ef6fef56758e87dfd3dbf770332d4915cf5 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 @@ -8,8 +8,8 @@ void test() { owned int arr1[10]; // 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]; // expected-error {{type of array cannot qualified by 'owned'(even indirectly), 'owned int *' contains 'owned' type}} - SA* arr4[3]; // expected-error {{type of array cannot qualified by 'owned'(even indirectly), 'SA *' (aka 'struct A *') contains 'owned' type}} + owned int* arr3[2]; + SA* arr4[3]; return; } 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 59ccedea92e6ad19524fc8ec092031b445ddb0d4..32c32c602fc1adae0d2bc69391714843ad290803 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 @@ -14,6 +14,6 @@ typedef struct B { SA* sa; }SB; -SB* sb1; //expected-error{{type of global variable cannot qualified by 'owned'(even indirectly), 'SB *' (aka 'struct B *') contains 'owned' type}} +SB* sb1; 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 fcbe3b152b4c1d5a7cf58b1a55ae10628c3bee9a..e9e56f17736892577a945fbe20137188ed4624d7 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 @@ -3,10 +3,10 @@ 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* p1; //expected-error {{type of global variable cannot qualified by 'owned'(even indirectly), 'owned int *' contains 'owned' type}} +int owned* p1; 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; //expected-error {{type of global variable cannot qualified by 'owned'(even indirectly), 'int *owned *' contains 'owned' type}} -owned int** p6; //expected-error {{type of global variable cannot qualified by 'owned'(even indirectly), 'owned int **' contains 'owned' type}} \ No newline at end of file +int* owned* p5; +owned int** p6; \ No newline at end of file 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 b0d7993b0005470f3f0d5bba21708442a7c879a7..3e2d0884b01f3085ae5f33cb816590418c2dd512 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 @@ -67,7 +67,7 @@ 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 int **c = (owned int**)&b; if(**c != 0) { return 1; } 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 2e0c7adbb4d46be44e0493dc7cb4d5d112defaa1..8ace5f000b21a1a30f3278191b7c49d30d1ddb1f 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 @@ -16,7 +16,7 @@ int main() { } union A { - owned int* a; //expected-error {{type of union field cannot qualified by 'owned'(even indirectly), 'owned int *' contains 'owned' type}} + owned int* a; }; typedef owned int ownedInt; @@ -29,5 +29,5 @@ struct S { }; union C { - struct S* s1; //expected-error {{type of union field cannot qualified by 'owned'(even indirectly), 'struct S *' contains 'owned' type}} + struct S* s1; }; 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 index 7189c46fd636a7c9bff767a8791b19bb6331912d..15ecc400f45110b479fffefd10ef8478dfb4a7bb 100644 --- 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 @@ -104,9 +104,7 @@ int main() { // CHECK-NEXT: int **c; // CHECK-NEXT: }; // CHECK-EMPTY: -// CHECK-NEXT: struct D { -// CHECK-NEXT: struct C c; -// CHECK-NEXT: }; +// CHECK-NEXT: struct D { struct C c; }; // CHECK-EMPTY: // CHECK-NEXT: struct E { // CHECK-NEXT: int e; @@ -174,7 +172,7 @@ int main() { // CHECK-NEXT: return 0; // CHECK-NEXT: } // CHECK-EMPTY: -// CHECK-NEXT: int main(void) { -// CHECK-NEXT: struct D *d; +// CHECK-NEXT: int main() { +// CHECK-NEXT: struct D * d; // CHECK-NEXT: return 0; // CHECK-NEXT: } diff --git a/libcbs/src/string/string.cbs b/libcbs/src/string/string.cbs index e9a2b5db55f605aabb10bdf4fca0656ebe3f1599..863dc1f5ff4bdfe12e68912a50ebea4b5b87f58e 100644 --- a/libcbs/src/string/string.cbs +++ b/libcbs/src/string/string.cbs @@ -96,9 +96,16 @@ safe void String::shrink_to_fit(String* borrow this) { } safe String String::slice(const String* borrow this, size_t start, size_t length) { - String string = String::with_capacity(length); - for (size_t i = start; i < length; i += 1) { - char c = this->at(i); + unsafe { + if (start >= this->length()) { + bsc_out_of_bound_handler(this->length(), start); + } + } + size_t len = this->length() - start; + len = len >= length ? length : len; + String string = String::with_capacity(len); + for (size_t i = 0; i < len; i += 1) { + char c = this->at(start + i); string.push(c); } string.push('\0');