From 9de1a26d7b2237d332cd88d7208f9a248297326a Mon Sep 17 00:00:00 2001 From: zhangziyao Date: Mon, 15 Dec 2025 19:03:47 +0800 Subject: [PATCH 1/2] [borrowck][bugfix] fixed the coredump in borrow checker when manipulating c style cast expr --- clang/lib/Analysis/BSC/BSCBorrowChecker.cpp | 9 +++++++-- .../cast_borrow_to_borrow.cbs | 17 +++++++++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 clang/test/BSC/Positive/Ownership/borrow_check_rules/cast_borrow_to_borrow/cast_borrow_to_borrow.cbs diff --git a/clang/lib/Analysis/BSC/BSCBorrowChecker.cpp b/clang/lib/Analysis/BSC/BSCBorrowChecker.cpp index 6988056cee8f..765415f72ae3 100644 --- a/clang/lib/Analysis/BSC/BSCBorrowChecker.cpp +++ b/clang/lib/Analysis/BSC/BSCBorrowChecker.cpp @@ -426,8 +426,13 @@ void ActionExtract::VisitCStyleCastExpr(CStyleCastExpr *CSCE) { } else { BK = borrow::BorrowKind::Mut; } - Kind = Action::Borrow; - bool AddDeref = Sources[0]->ty != Dest->ty->getPointeeType(); + if (!Sources[0]->ty.isBorrowQualified()) { + Kind = Action::Borrow; + } + bool AddDeref = false; + if (Dest) { + AddDeref = Sources[0]->ty != Dest->ty->getPointeeType(); + } if (UnaryOperator *Sub = dyn_cast( CSCE->getSubExpr()->IgnoreParenImpCasts())) { if (Sub->getOpcode() == UO_AddrOf) { diff --git a/clang/test/BSC/Positive/Ownership/borrow_check_rules/cast_borrow_to_borrow/cast_borrow_to_borrow.cbs b/clang/test/BSC/Positive/Ownership/borrow_check_rules/cast_borrow_to_borrow/cast_borrow_to_borrow.cbs new file mode 100644 index 000000000000..209096c7c887 --- /dev/null +++ b/clang/test/BSC/Positive/Ownership/borrow_check_rules/cast_borrow_to_borrow/cast_borrow_to_borrow.cbs @@ -0,0 +1,17 @@ +// 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 + +int *borrow return_and_take_nonnull(int *borrow a) { + return a; +} + +int main(void) { + int a = 10; + int *borrow p = &mut a; + return_and_take_nonnull((int *borrow)p); + return 0; +} \ No newline at end of file -- Gitee From 1acbb8ccdea13526740ab8fb8ad8ee086579a330 Mon Sep 17 00:00:00 2001 From: zhangziyao Date: Mon, 15 Dec 2025 21:15:29 +0800 Subject: [PATCH 2/2] [borrow][bugfix] fixed the bug that allows implicit conversion from borrow pointer to raw pointer --- clang/lib/Sema/BSC/SemaBSCOwnership.cpp | 3 ++- .../borrow_implicit_cast_to_raw.cbs | 20 +++++++++++++++++++ .../Borrow/borrow_trait/borrow_trait.cbs | 1 - .../owned_trait_fun_call.cbs | 4 ---- libcbs/src/hash/sip.cbs | 20 +++++++++---------- 5 files changed, 32 insertions(+), 16 deletions(-) create mode 100644 clang/test/BSC/Negative/Ownership/Borrow/borrow_implicit_cast_to_raw/borrow_implicit_cast_to_raw.cbs diff --git a/clang/lib/Sema/BSC/SemaBSCOwnership.cpp b/clang/lib/Sema/BSC/SemaBSCOwnership.cpp index c197a8c5ff22..1f918160fccb 100644 --- a/clang/lib/Sema/BSC/SemaBSCOwnership.cpp +++ b/clang/lib/Sema/BSC/SemaBSCOwnership.cpp @@ -340,7 +340,8 @@ bool Sema::CheckBorrowQualTypeAssignment(QualType LHSType, Expr* RHSExpr) { return true; if (LHSCanType->isVoidPointerType()) { - if (LHSCanType->getPointeeType().isConstQualified() == RHSCanType->getPointeeType().isConstQualified()) + if (LHSCanType->getPointeeType().isConstQualified() == RHSCanType->getPointeeType().isConstQualified() && + LHSCanType.isBorrowQualified() == RHSCanType.isBorrowQualified()) return true; } if (!Context.hasSameType(LHSCanType, RHSCanType)) diff --git a/clang/test/BSC/Negative/Ownership/Borrow/borrow_implicit_cast_to_raw/borrow_implicit_cast_to_raw.cbs b/clang/test/BSC/Negative/Ownership/Borrow/borrow_implicit_cast_to_raw/borrow_implicit_cast_to_raw.cbs new file mode 100644 index 000000000000..25a67fb1783e --- /dev/null +++ b/clang/test/BSC/Negative/Ownership/Borrow/borrow_implicit_cast_to_raw/borrow_implicit_cast_to_raw.cbs @@ -0,0 +1,20 @@ +// RUN: %clang_cc1 -verify %s + +void *malloc(unsigned long); + +void log_print(void *msg, const char *pcFormat, ...){} + +#define bsc_log_print(msg, pcFormat, ...) \ + unsafe {log_print(msg, pcFormat, ##__VA_ARGS__);} + +safe T* owned _Nullable bsc_malloc(int size) { + unsafe {return (T* owned _Nullable )malloc(size);} +} + +int main() { + void * owned _Nullable pMsg = nullptr; + pMsg = bsc_malloc(100); + bsc_log_print(&mut *pMsg, "Info: no memory!"); // expected-error {{incompatible borrow types, cannot cast 'void *borrow' to 'void *'}} + void * a = (void *)pMsg; + return 0; +} diff --git a/clang/test/BSC/Negative/Ownership/Borrow/borrow_trait/borrow_trait.cbs b/clang/test/BSC/Negative/Ownership/Borrow/borrow_trait/borrow_trait.cbs index 5535d154a181..c12a40259c7d 100644 --- a/clang/test/BSC/Negative/Ownership/Borrow/borrow_trait/borrow_trait.cbs +++ b/clang/test/BSC/Negative/Ownership/Borrow/borrow_trait/borrow_trait.cbs @@ -17,6 +17,5 @@ int main() { trait T* borrow p = &mut *t; a = 2; t = &a; - p->f(); return 0; } \ No newline at end of file diff --git a/clang/test/BSC/Negative/Ownership/Owned/owned_trait_fun_call/owned_trait_fun_call.cbs b/clang/test/BSC/Negative/Ownership/Owned/owned_trait_fun_call/owned_trait_fun_call.cbs index 1d5cad3471d9..beae1dc41686 100644 --- a/clang/test/BSC/Negative/Ownership/Owned/owned_trait_fun_call/owned_trait_fun_call.cbs +++ b/clang/test/BSC/Negative/Ownership/Owned/owned_trait_fun_call/owned_trait_fun_call.cbs @@ -44,7 +44,6 @@ void test1() { trait T* t = &x; t->do_it(); // expected-error {{incompatible owned types, cannot cast 'void *' to 'void *owned'}} t->do_that(); - t->do_this(); } void test2() { @@ -59,7 +58,6 @@ void test3() { int x = 1; trait T* borrow t = &mut x; t->do_it(); // expected-error {{incompatible owned types, cannot cast 'void *borrow' to 'void *owned'}} - t->do_that(); t->do_this(); } @@ -73,7 +71,6 @@ void test4() { trait T* t = s; t->do_it(); // expected-error {{incompatible owned types, cannot cast 'void *' to 'void *owned'}} t->do_that(); - t->do_this(); } void test5() { @@ -89,6 +86,5 @@ void test6() { struct S s = initS(); trait T* borrow t= &mut s; t->do_it(); // expected-error {{incompatible owned types, cannot cast 'void *borrow' to 'void *owned'}} - t->do_that(); t->do_this(); } diff --git a/libcbs/src/hash/sip.cbs b/libcbs/src/hash/sip.cbs index 18109f7cddbf..43184db0ddc7 100644 --- a/libcbs/src/hash/sip.cbs +++ b/libcbs/src/hash/sip.cbs @@ -125,60 +125,60 @@ SipHasher13 SipHasher13::new_with_keys(uint64_t key0, uint64_t key1) { uint64_t int::hash(const int* borrow this, SipHasher13* borrow sh) { size_t count = sizeof(int) > 8 ? 8 : sizeof(int); - memcpy(&sh->k0, this, count); + memcpy(&sh->k0, (const void *)this, count); return sh->finish(); } uint64_t unsigned int::hash(const unsigned int* borrow this, SipHasher13* borrow sh) { size_t count = sizeof(unsigned int) > 8 ? 8 : sizeof(unsigned int); - memcpy(&sh->k0, this, count); + memcpy(&sh->k0, (const void *)this, count); return sh->finish(); } uint64_t long::hash(const long* borrow this, SipHasher13* borrow sh) { size_t count = sizeof(long) > 8 ? 8 : sizeof(long); - memcpy(&sh->k0, this, count); + memcpy(&sh->k0, (const void *)this, count); return sh->finish(); } uint64_t unsigned long::hash(const unsigned long* borrow this, SipHasher13* borrow sh) { size_t count = sizeof(unsigned long) > 8 ? 8 : sizeof(unsigned long); - memcpy(&sh->k0, this, count); + memcpy(&sh->k0, (const void *)this, count); return sh->finish(); } uint64_t short::hash(const short* borrow this, SipHasher13* borrow sh) { size_t count = sizeof(short) > 8 ? 8 : sizeof(short); - memcpy(&sh->k0, this, count); + memcpy(&sh->k0, (const void *)this, count); return sh->finish(); } uint64_t unsigned short::hash(const unsigned short* borrow this, SipHasher13* borrow sh) { size_t count = sizeof(unsigned short) > 8 ? 8 : sizeof(unsigned short); - memcpy(&sh->k0, this, count); + memcpy(&sh->k0, (const void *)this, count); return sh->finish(); } uint64_t char::hash(const char* borrow this, SipHasher13* borrow sh) { size_t count = sizeof(char) > 8 ? 8 : sizeof(char); - memcpy(&sh->k0, this, count); + memcpy(&sh->k0, (const void *)this, count); return sh->finish(); } uint64_t unsigned char::hash(const unsigned char* borrow this, SipHasher13* borrow sh) { size_t count = sizeof(unsigned char) > 8 ? 8 : sizeof(unsigned char); - memcpy(&sh->k0, this, count); + memcpy(&sh->k0, (const void *)this, count); return sh->finish(); } uint64_t long long::hash(const long long* borrow this, SipHasher13* borrow sh) { size_t count = sizeof(long long) > 8 ? 8 : sizeof(long long); - memcpy(&sh->k0, this, count); + memcpy(&sh->k0, (const void *)this, count); return sh->finish(); } uint64_t unsigned long long::hash(const unsigned long long* borrow this, SipHasher13* borrow sh) { size_t count = sizeof(unsigned long long) > 8 ? 8 : sizeof(unsigned long long); - memcpy(&sh->k0, this, count); + memcpy(&sh->k0, (const void *)this, count); return sh->finish(); } -- Gitee