diff --git a/clang/lib/Analysis/BSCBorrowCheck.cpp b/clang/lib/Analysis/BSCBorrowCheck.cpp index 3f3268886062f10a1f9085d518890d61e93c9ba5..d607c6b82e183068bb1e7d240e522c5cee7aa230 100644 --- a/clang/lib/Analysis/BSCBorrowCheck.cpp +++ b/clang/lib/Analysis/BSCBorrowCheck.cpp @@ -1584,6 +1584,8 @@ void NLLCalculator::VisitMEForFieldPath( VisitMEForFieldPath(ASE->getBase(), VDAndFP); } else if (auto CCE = dyn_cast(E)) { VisitMEForFieldPath(CCE->getSubExpr(), VDAndFP); + } else if (auto CE = dyn_cast(E)) { + VisitMEForFieldPath(CE->getArg(0), VDAndFP); } } diff --git a/clang/lib/Analysis/BSCOwnership.cpp b/clang/lib/Analysis/BSCOwnership.cpp index b0cb3b4d6d3ccb7e852fc90644284685431fb3e1..fcc8e7600332c9a84c94b7eb875ffe09cb19c912 100644 --- a/clang/lib/Analysis/BSCOwnership.cpp +++ b/clang/lib/Analysis/BSCOwnership.cpp @@ -2243,6 +2243,8 @@ void clang::runOwnershipAnalysis(const FunctionDecl &fd, const CFG &cfg, reporter.addDiags(diags); } } + + delete OS; } #endif // ENABLE_BSC \ No newline at end of file diff --git a/clang/lib/Parse/BSC/ParseDeclBSC.cpp b/clang/lib/Parse/BSC/ParseDeclBSC.cpp index adc2e325aa896701e8a1b7950b0ec5400748b8fe..53b7cce6c36e62c8bc4d16c93897d9c54cffb4d3 100644 --- a/clang/lib/Parse/BSC/ParseDeclBSC.cpp +++ b/clang/lib/Parse/BSC/ParseDeclBSC.cpp @@ -1283,7 +1283,14 @@ Parser::ParseBSCClassMemberDeclaration(AccessSpecifier AS, SuppressAccessChecks diagsFromTag(*this, IsTemplateSpecOrInst); ParseDeclarationSpecifiers(DS, TemplateInfo, AS, DeclSpecContext::DSC_class, - &CommonLateParsedAttrs); // + &CommonLateParsedAttrs); + + // Issue diagnostic and remove `typedef` if present. + if (DS.getStorageClassSpec() == DeclSpec::SCS_typedef && + DS.getStorageClassSpecLoc().isValid()) { + Diag(DS.getStorageClassSpecLoc(),diag::err_typename_invalid_storageclass); + DS.ClearStorageClassSpecs(); + } if (IsTemplateSpecOrInst) diagsFromTag.done(); diff --git a/clang/test/BSC/Negative/OwnedStruct/field-decl/field-decl.cbs b/clang/test/BSC/Negative/OwnedStruct/field-decl/field-decl.cbs new file mode 100644 index 0000000000000000000000000000000000000000..56b0b0f146038ee3912eacb670fa93491e10c5db --- /dev/null +++ b/clang/test/BSC/Negative/OwnedStruct/field-decl/field-decl.cbs @@ -0,0 +1,32 @@ +// RUN: %clang_cc1 -verify %s + +owned struct S { +public: + typedef int Int; // expected-error {{type name does not allow storage class to be specified}} + Int y; // expected-error {{unknown type name 'Int'; did you mean 'int'?}} + ~S(S this) { + typedef double Double; + Double d = 1.0; + } +}; + +owned struct GS { +public: + typedef int Int; // expected-error {{type name does not allow storage class to be specified}} + Int y; // expected-error {{unknown type name 'Int'; did you mean 'int'?}} + typedef T type; // expected-error {{type name does not allow storage class to be specified}} +}; + +owned struct U { +public: + typedef GS gs_t; // expected-error {{type name does not allow storage class to be specified}} + gs_t gs; // expected-error {{unknown type name 'gs_t'}} +}; + +owned struct UU { +public: + typedef Int = int; // expected-error {{type name does not allow storage class to be specified}} + // expected-error@-1 {{expected ';' at end of declaration list}} + // expected-warning@-2 {{type specifier missing, defaults to 'int'; ISO C99 and later do not support implicit int}} + Int y; // expected-error {{unknown type name 'Int'; did you mean 'int'?}} +}; diff --git a/clang/test/BSC/Negative/Ownership/Borrow/borrow_check_rules/nested_call_and_member/nested_call_and_member.cbs b/clang/test/BSC/Negative/Ownership/Borrow/borrow_check_rules/nested_call_and_member/nested_call_and_member.cbs new file mode 100644 index 0000000000000000000000000000000000000000..524bdf00f2b2e84487a020f53ba8fbed9096e963 --- /dev/null +++ b/clang/test/BSC/Negative/Ownership/Borrow/borrow_check_rules/nested_call_and_member/nested_call_and_member.cbs @@ -0,0 +1,39 @@ +// RUN: %clang_cc1 -verify %s + +struct sockaddr; + +typedef struct v5_adpt_socket { +} v5_adpt_socket_t; + +owned struct ListNode { +public: + v5_adpt_socket_t inner; +}; + +owned struct OptionRefMut { +public: + ListNode* borrow inner; +}; + +OptionRefMut socket_table_find(int* borrow); +ListNode* borrow OptionRefMut::unwrap(OptionRefMut* borrow this); +ListNode* owned AllocSocket(); +void accept(int, struct sockaddr *, int *); +void SkAcceptInfoSet(const v5_adpt_socket_t* borrow, v5_adpt_socket_t* borrow); +void CloseSocket(v5_adpt_socket_t *); +void use(ListNode* borrow); + +void v5_accept(int fd, void* addr, int* addrLen, int* borrow p) { + OptionRefMut o = socket_table_find(p); + const v5_adpt_socket_t* borrow ls = &const o.unwrap()->inner; // expected-note {{previous borrow is here}} + use(o.inner); // expected-error {{There should be at most one mutable borrow targeting to 'p' at the same time}} + ListNode* owned t = AllocSocket(); + { + v5_adpt_socket_t* borrow s = &mut t->inner; + accept(fd, (struct sockaddr *)addr, addrLen); + SkAcceptInfoSet(ls, s); + } + v5_adpt_socket_t* borrow s = &mut t->inner; + ListNode* t1 = (ListNode *)t; + CloseSocket((v5_adpt_socket_t*)s); +}