diff --git a/clang/include/clang/Analysis/Analyses/BSC/BSCBorrowChecker.h b/clang/include/clang/Analysis/Analyses/BSC/BSCBorrowChecker.h index 7fbca6ef031740958b1b90882cbae3722bfcf952..dada516dc83a85ea899ce925968db22fd17766a5 100644 --- a/clang/include/clang/Analysis/Analyses/BSC/BSCBorrowChecker.h +++ b/clang/include/clang/Analysis/Analyses/BSC/BSCBorrowChecker.h @@ -939,7 +939,7 @@ private: std::map>> actionMap; void PopulateInference(Liveness &liveness); - RegionVariable getRegionVariable(RegionName RV); + RegionVariable getRegionVariable(RegionName RN); void EnsureBorrowSource(Point SuccPoint, RegionName BorrowRegionName, const std::unique_ptr &SourcePath); void RelateRegions(Point SuccPoint, RegionName Sub, RegionName Sup); diff --git a/clang/lib/Analysis/BSC/BSCBorrowChecker.cpp b/clang/lib/Analysis/BSC/BSCBorrowChecker.cpp index 28c6de15182bab27794e852bfc7602269147c05c..4d58e313b5caf580f84261494ce1cfeb778deec7 100644 --- a/clang/lib/Analysis/BSC/BSCBorrowChecker.cpp +++ b/clang/lib/Analysis/BSC/BSCBorrowChecker.cpp @@ -1557,6 +1557,8 @@ RegionName RegionCheck::getRegionName(Decl *D) { << RN.print() << '\n'; #endif declToRegionNameMap[D] = RN; + // Ensure that the region variable corresponding to RN exists. + (void)getRegionVariable(RN); return RN; } @@ -1569,6 +1571,8 @@ RegionName RegionCheck::getRegionName(Stmt *S) { << '\n'; #endif stmtToRegionNameMap[S] = RN; + // Ensure that the region variable corresponding to RN exists. + (void)getRegionVariable(RN); return RN; } diff --git a/clang/lib/Analysis/CFG.cpp b/clang/lib/Analysis/CFG.cpp index 2d48e8a945af0e01df4b03d2c5044d488db42034..b52d888344929cb5252feb46bf77345fcf921db1 100644 --- a/clang/lib/Analysis/CFG.cpp +++ b/clang/lib/Analysis/CFG.cpp @@ -2150,6 +2150,14 @@ CFGBlock *CFGBuilder::Visit(Stmt * S, AddStmtChoice asc, default: return VisitStmt(S, asc); +#if ENABLE_BSC + case Stmt::SafeStmtClass: + return Visit(cast(S)->getSubStmt(), asc, ExternallyDestructed); + + case Stmt::SafeExprClass: + return Visit(cast(S)->getSubExpr(), asc, ExternallyDestructed); +#endif + case Stmt::ImplicitValueInitExprClass: if (BuildOpts.OmitImplicitValueInitializers) return Block; diff --git a/clang/test/BSC/Positive/Ownership/borrow_check_rules/borrow_in_safe_expr_and_stmt/borrow_in_safe_expr_and_stmt.cbs b/clang/test/BSC/Positive/Ownership/borrow_check_rules/borrow_in_safe_expr_and_stmt/borrow_in_safe_expr_and_stmt.cbs new file mode 100644 index 0000000000000000000000000000000000000000..541bddd883de2f2d896c05081cbfda8986602bbc --- /dev/null +++ b/clang/test/BSC/Positive/Ownership/borrow_check_rules/borrow_in_safe_expr_and_stmt/borrow_in_safe_expr_and_stmt.cbs @@ -0,0 +1,86 @@ +// 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 +// expected-no-diagnostics + +safe void use(int *borrow p) { + *p = 5; +} + +void test1(int a, int b, char c) { + safe switch (a) { + case 5: { + int *borrow pb = &mut b; + use(pb); + break; + } + default: + c += 1; + } +} + +void test2(int a, int b, char c) { + safe switch (a) { + case 0: + a += 1; + break; + case 1: + a += 2; + case 2: + case 3: + break; + case 4: { + c += 1; + break; + } + case 5: { + int *borrow pb = &mut b; + use(pb); + break; + } + case 6: + unsafe { + safe { + unsafe { + safe switch (c) { + case 0: + a+=1; + break; + case 1: + a += 2; + case 2: + case 3: + break; + case 4: { + c += 1; + break; + } + case 5: { + int *borrow pb = &mut b; + use(pb); + break; + } + default: + c += 1; + } + break; + } + } + } + case 7: + unsafe { + a++; + break; + } + default: + c += 1; + } +} + +int main(void) { + test1(5, 2, '3'); + test2(1, 2, '3'); + return 0; +} diff --git a/clang/test/BSC/Positive/Ownership/borrow_check_rules/reborrow_raw_pointers/reborrow_raw_pointers.cbs b/clang/test/BSC/Positive/Ownership/borrow_check_rules/reborrow_raw_pointers/reborrow_raw_pointers.cbs new file mode 100644 index 0000000000000000000000000000000000000000..a046c16d07829070693a18a0f1bcf5ea8c4cbda6 --- /dev/null +++ b/clang/test/BSC/Positive/Ownership/borrow_check_rules/reborrow_raw_pointers/reborrow_raw_pointers.cbs @@ -0,0 +1,24 @@ +// 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 +// expected-no-diagnostics + +void call1(int *borrow p, int *raw) { + p = &mut *raw; +} + +void call2(const int *borrow q, int x) { + q = &const x; +} + +int main() { + int a = 1, b = 2; + int *raw = &a; + int *borrow p = &mut a; + const int *borrow q = &const b; + call1(p, raw); + call2(q, 2); + return 0; +} \ No newline at end of file