diff --git a/clang/include/clang/Basic/BSC/DiagnosticBSCSemaKinds.td b/clang/include/clang/Basic/BSC/DiagnosticBSCSemaKinds.td index 3febc8c33974e947807d4e72543c41a493ffb91b..2fa516bc0c1d4b93c7e8cb33f9df4e026fa6958f 100644 --- a/clang/include/clang/Basic/BSC/DiagnosticBSCSemaKinds.td +++ b/clang/include/clang/Basic/BSC/DiagnosticBSCSemaKinds.td @@ -65,7 +65,7 @@ def err_owned_temporary_memLeak : Error< "memory leak because temporary variable '%0' is owned or indirect owned type, please fix it">; def err_funcPtr_incompatible : Error< "incompatible borrow function pointer types, cannot cast %0 to %1">; -def err_borrow_on_borrow : Error<"%0 on a 'borrow' quialified type is not allowed">; +def err_borrow_on_borrow : Error<"%0 on a 'borrow' qualified type is not allowed">; def err_mut_expr_unmodifiable : Error<"the expression after '&mut' must be modifiable">; def err_mut_expr_func : Error<"'&mut' for function pointer is not allowed">; def err_safe_mut : Error<"global or static variables are not allowed to be mutably borrowed within the safe zone">; diff --git a/clang/lib/Sema/BSC/SemaBSCOwnership.cpp b/clang/lib/Sema/BSC/SemaBSCOwnership.cpp index c96493b7f583a7b2f924ae5c3e054c50a098b131..c197a8c5ff22211b0c0296782f1f988c5302cdb5 100644 --- a/clang/lib/Sema/BSC/SemaBSCOwnership.cpp +++ b/clang/lib/Sema/BSC/SemaBSCOwnership.cpp @@ -367,9 +367,15 @@ bool Sema::CheckBorrowQualTypeCompare(QualType LHSType, QualType RHSType) { } void Sema::CheckBorrowFunctionType(QualType ReturnTy, SmallVector ParamTys, SourceLocation SL) { + if (ReturnTy->isDependentType()) { + return; + } if (ReturnTy.hasBorrow()) { bool HasBorrowParam = false; for (QualType PT : ParamTys) { + if (PT->isDependentType()) { + return; + } if (PT.hasBorrow()) { HasBorrowParam = true; break; diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp index ddc38107a9ead7a847484c7f43d04202914790ae..37def7ff1d965244fa7a4fe6ba29bcea7b6f55ac 100644 --- a/clang/lib/Sema/SemaExpr.cpp +++ b/clang/lib/Sema/SemaExpr.cpp @@ -14923,7 +14923,7 @@ QualType Sema::GetBorrowAddressOperandQualType(QualType resultType, if (Opc == UO_AddrMut && IsAddrBorrowDerefOp(Input)) { Opc = UO_AddrMutDeref; } else { - if (InputExpr->getType().hasBorrow()) + if (Opc == UO_AddrMut && InputExpr->getType().hasBorrow()) Diag(OpLoc, diag::err_borrow_on_borrow) << "'&mut'" << InputExpr->getSourceRange(); if (InputExpr->getType().isConstQualified()) @@ -14956,7 +14956,7 @@ QualType Sema::GetBorrowAddressOperandQualType(QualType resultType, if (Opc == UO_AddrConst && IsAddrBorrowDerefOp(Input)) { Opc = UO_AddrConstDeref; } else { - if (InputExpr->getType().hasBorrow()) + if (Opc == UO_AddrConst && InputExpr->getType().hasBorrow()) Diag(OpLoc, diag::err_borrow_on_borrow) << "'&const'" << InputExpr->getSourceRange(); } diff --git a/clang/test/BSC/Negative/Ownership/Borrow/borrow_on_borrow/borrow_on_borrow.cbs b/clang/test/BSC/Negative/Ownership/Borrow/borrow_on_borrow/borrow_on_borrow.cbs index aebd4ad4c86bbb7cc035a2b0fba0a13b6fd3d89c..00ef6f9238b1f4e5578d57944c737cb27fbab0bb 100644 --- a/clang/test/BSC/Negative/Ownership/Borrow/borrow_on_borrow/borrow_on_borrow.cbs +++ b/clang/test/BSC/Negative/Ownership/Borrow/borrow_on_borrow/borrow_on_borrow.cbs @@ -9,48 +9,48 @@ void test() { int b = 1; int *borrow p1 = &mut a; // legal const int *borrow p2 = &const b; // legal - int *borrow * borrow b1 = &mut p1; // expected-error {{'&mut' on a 'borrow' quialified type is not allowed}} + int *borrow * borrow b1 = &mut p1; // expected-error {{'&mut' on a 'borrow' qualified type is not allowed}} const int *borrow const * borrow b2 = &const p2; /* expected-error {{incompatible borrow types, cannot cast 'const int *borrow *borrow' to 'const int *const borrow *borrow'}} - expected-error {{'&const' on a 'borrow' quialified type is not allowed}} */ + expected-error {{'&const' on a 'borrow' qualified type is not allowed}} */ int *borrow const * borrow b3 = &const p1; /* expected-error {{incompatible borrow types, cannot cast 'const int *borrow *borrow' to 'int *const borrow *borrow'}} - expected-error {{'&const' on a 'borrow' quialified type is not allowed}} */ - const int * borrow * borrow b4 = &mut p2; // expected-error {{'&mut' on a 'borrow' quialified type is not allowed}} - int *borrow *borrow p3 = &mut (&mut a); // expected-error {{'&mut' on a 'borrow' quialified type is not allowed}} expected-error {{cannot take the address of an rvalue of type 'int *borrow'}} - const int *borrow *borrow p4 = &mut (&const b); // expected-error {{'&mut' on a 'borrow' quialified type is not allowed}} expected-error {{cannot take the address of an rvalue of type 'const int *borrow'}} + expected-error {{'&const' on a 'borrow' qualified type is not allowed}} */ + const int * borrow * borrow b4 = &mut p2; // expected-error {{'&mut' on a 'borrow' qualified type is not allowed}} + int *borrow *borrow p3 = &mut (&mut a); // expected-error {{'&mut' on a 'borrow' qualified type is not allowed}} expected-error {{cannot take the address of an rvalue of type 'int *borrow'}} + const int *borrow *borrow p4 = &mut (&const b); // expected-error {{'&mut' on a 'borrow' qualified type is not allowed}} expected-error {{cannot take the address of an rvalue of type 'const int *borrow'}} const int *borrow const * borrow p5 = &const (&const b); /* expected-error {{cannot take the address of an rvalue of type 'const int *borrow'}} - expected-error {{'&const' on a 'borrow' quialified type is not allowed}} */ + expected-error {{'&const' on a 'borrow' qualified type is not allowed}} */ int *borrow const * borrow p6 = &const (&mut a); /* expected-error {{cannot take the address of an rvalue of type 'int *borrow'}} - expected-error {{'&const' on a 'borrow' quialified type is not allowed}} */ + expected-error {{'&const' on a 'borrow' qualified type is not allowed}} */ int *borrow *borrow *borrow p7 = &mut (&mut (&mut a)); /* expected-error {{cannot take the address of an rvalue of type 'int *borrow'}} - expected-error {{'&mut' on a 'borrow' quialified type is not allowed}} */ + expected-error {{'&mut' on a 'borrow' qualified type is not allowed}} */ const int *borrow *borrow *borrow p8 = &mut (&mut (&const a)); /* expected-error {{cannot take the address of an rvalue of type 'const int *borrow'}} - expected-error {{'&mut' on a 'borrow' quialified type is not allowed}}*/ - &mut p1; /* expected-error {{'&mut' on a 'borrow' quialified type is not allowed}} + expected-error {{'&mut' on a 'borrow' qualified type is not allowed}}*/ + &mut p1; /* expected-error {{'&mut' on a 'borrow' qualified type is not allowed}} expected-warning {{expression result unused}} */ - &const p1;/* expected-error {{'&const' on a 'borrow' quialified type is not allowed}} + &const p1;/* expected-error {{'&const' on a 'borrow' qualified type is not allowed}} expected-warning {{expression result unused}} */ - &mut p2; /* expected-error {{'&mut' on a 'borrow' quialified type is not allowed}} + &mut p2; /* expected-error {{'&mut' on a 'borrow' qualified type is not allowed}} expected-warning {{expression result unused}} */ - &const p2; /* expected-error {{'&const' on a 'borrow' quialified type is not allowed}} + &const p2; /* expected-error {{'&const' on a 'borrow' qualified type is not allowed}} expected-warning {{expression result unused}} */ &mut (&mut a); /* expected-error {{cannot take the address of an rvalue of type 'int *borrow'}} - expected-error {{'&mut' on a 'borrow' quialified type is not allowed}} */ + expected-error {{'&mut' on a 'borrow' qualified type is not allowed}} */ &const (&const b);/* expected-error {{cannot take the address of an rvalue of type 'const int *borrow'}} - expected-error {{'&const' on a 'borrow' quialified type is not allowed}}*/ + expected-error {{'&const' on a 'borrow' qualified type is not allowed}}*/ &mut (&mut a);/* expected-error {{cannot take the address of an rvalue of type 'int *borrow'}} - expected-error {{'&mut' on a 'borrow' quialified type is not allowed}}*/ + expected-error {{'&mut' on a 'borrow' qualified type is not allowed}}*/ &const (&const b); /* expected-error {{cannot take the address of an rvalue of type 'const int *borrow'}} - expected-error {{'&const' on a 'borrow' quialified type is not allowed}}*/ + expected-error {{'&const' on a 'borrow' qualified type is not allowed}}*/ &p1; // expected-warning {{expression result unused}} &p2; // expected-warning {{expression result unused}} & (&mut a); // expected-error {{cannot take the address of an rvalue of type 'int *borrow'}} & (&const b); // expected-error {{cannot take the address of an rvalue of type 'const int *borrow'}} struct R r = { 1, &mut a }; - struct R * borrow pr = &mut r; // expected-error {{'&mut' on a 'borrow' quialified type is not allowed}} - const struct R * borrow pr2 = &const r; // expected-error {{'&const' on a 'borrow' quialified type is not allowed}} - &const r.p1; /* expected-error {{'&const' on a 'borrow' quialified type is not allowed}} + struct R * borrow pr = &mut r; // expected-error {{'&mut' on a 'borrow' qualified type is not allowed}} + const struct R * borrow pr2 = &const r; // expected-error {{'&const' on a 'borrow' qualified type is not allowed}} + &const r.p1; /* expected-error {{'&const' on a 'borrow' qualified type is not allowed}} expected-warning {{expression result unused}} */ - &mut r.p1; /* expected-error {{'&mut' on a 'borrow' quialified type is not allowed}} + &mut r.p1; /* expected-error {{'&mut' on a 'borrow' qualified type is not allowed}} expected-warning {{expression result unused}} */ } \ No newline at end of file diff --git a/clang/test/BSC/Negative/Ownership/Borrow/borrow_op/borrow_op.cbs b/clang/test/BSC/Negative/Ownership/Borrow/borrow_op/borrow_op.cbs index 0339a977e339ced0332d6c7716904cae53c6a4e6..97cb1b2cba85317b7c94a75237c0fd14cab2423b 100644 --- a/clang/test/BSC/Negative/Ownership/Borrow/borrow_op/borrow_op.cbs +++ b/clang/test/BSC/Negative/Ownership/Borrow/borrow_op/borrow_op.cbs @@ -59,13 +59,13 @@ int test() { ~p5; // expected-error {{invalid argument type 'const int *borrow' to unary expression}} p5 << 6; // expected-error {{invalid operands to binary expression ('const int *borrow' and 'int')}} p3 >> p4; // expected-error {{invalid operands to binary expression ('int *borrow' and 'int *borrow')}} - &mut p3; // expected-error {{'&mut' on a 'borrow' quialified type is not allowed}} + &mut p3; // expected-error {{'&mut' on a 'borrow' qualified type is not allowed}} // expected-warning@-1 {{expression result unused}} - &mut p5; // expected-error {{'&mut' on a 'borrow' quialified type is not allowed}} + &mut p5; // expected-error {{'&mut' on a 'borrow' qualified type is not allowed}} // expected-warning@-1 {{expression result unused}} - &const p3; // expected-error {{'&const' on a 'borrow' quialified type is not allowed}} + &const p3; // expected-error {{'&const' on a 'borrow' qualified type is not allowed}} // expected-warning@-1 {{expression result unused}} - &const p5; // expected-error {{'&const' on a 'borrow' quialified type is not allowed}} + &const p5; // expected-error {{'&const' on a 'borrow' qualified type is not allowed}} // expected-warning@-1 {{expression result unused}} // unary -- ++ diff --git a/clang/test/BSC/Positive/Ownership/generic_struct_with_borrow_field/generic_struct_with_borrow_field.cbs b/clang/test/BSC/Positive/Ownership/generic_struct_with_borrow_field/generic_struct_with_borrow_field.cbs new file mode 100644 index 0000000000000000000000000000000000000000..0b9cecdbc675e30633dd3186e83207a80147027c --- /dev/null +++ b/clang/test/BSC/Positive/Ownership/generic_struct_with_borrow_field/generic_struct_with_borrow_field.cbs @@ -0,0 +1,21 @@ +// RUN: %clang %s -o %t.output +// RUN: %t.output +// expected-no-diagnostics + +struct S { + int a; + T *borrow b; +}; + +T *borrow test(struct S s) { + return s.b; +} + +int main(void) { + int a = 2; + struct S s = { 1, &mut a }; + int *borrow p = test(s); + *p = 3; + if (a == 3) return 0; + return 1; +} \ No newline at end of file diff --git a/clang/test/BSC/Positive/Ownership/reborrow_in_generic/reborrow_in_generic.cbs b/clang/test/BSC/Positive/Ownership/reborrow_in_generic/reborrow_in_generic.cbs new file mode 100644 index 0000000000000000000000000000000000000000..8174168babf8e963e1a81a350fa310854a559bc3 --- /dev/null +++ b/clang/test/BSC/Positive/Ownership/reborrow_in_generic/reborrow_in_generic.cbs @@ -0,0 +1,31 @@ +// RUN: %clang %s -o %t.output +// RUN: %t.output +// expected-no-diagnostics + +void use(int *borrow p) { + *p = 2; +} + +void use_immut(const int *borrow p) { + int x = *p; +} + +void test1() { + int a = 1; + int *borrow p = &mut a; + int *borrow q = &mut *p; + use(q); +} + +void test2() { + int a = 1; + int *borrow p = &mut a; + const int *borrow q = &const *p; + use_immut(q); +} + +int main() { + test1(); + test2(); + return 0; +}