diff --git a/cpp2rust/converter/converter.cpp b/cpp2rust/converter/converter.cpp index 59943ad2..219e041a 100644 --- a/cpp2rust/converter/converter.cpp +++ b/cpp2rust/converter/converter.cpp @@ -1689,7 +1689,7 @@ std::string Converter::GetEscapedUTF8CharLiteral(clang::Expr *expr) const { } std::string Converter::GetEscapedStringLiteral(clang::Expr *expr, - bool add_null_char) const { + uint64_t pad_nulls) const { auto str_expr = clang::dyn_cast(expr->IgnoreCasts()); assert(str_expr); auto raw = str_expr->getString(); @@ -1698,7 +1698,7 @@ std::string Converter::GetEscapedStringLiteral(clang::Expr *expr, for (unsigned char c : raw) { out += GetEscapedCharLiteral(static_cast(c)); } - if (add_null_char) { + for (uint64_t i = 0; i < pad_nulls; ++i) { out += "\\0"; } out.push_back('"'); @@ -1706,7 +1706,23 @@ std::string Converter::GetEscapedStringLiteral(clang::Expr *expr, } bool Converter::VisitStringLiteral(clang::StringLiteral *expr) { - StrCat(std::format("b{}.as_ptr()", GetEscapedStringLiteral(expr, true))); + if (!curr_init_type_.empty() && curr_init_type_.top()->isArrayType()) { + if (auto *arr_ty = ctx_.getAsConstantArrayType(curr_init_type_.top())) { + uint64_t arr_size = arr_ty->getSize().getZExtValue(); + if (expr->getString().empty()) { + StrCat(std::format("[0u8; {}]", arr_size)); + return false; + } + uint64_t pad = arr_size > expr->getString().size() + ? arr_size - expr->getString().size() + : 0; + StrCat(token::kStar, + std::format("b{}", GetEscapedStringLiteral(expr, pad))); + return false; + } + StrCat(token::kStar); + } + StrCat(std::format("b{}", GetEscapedStringLiteral(expr, 1))); return false; } @@ -1726,23 +1742,26 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) { SetValueFreshness(type); break; } - case clang::CastKind::CK_ArrayToPointerDecay: - if (clang::isa(sub_expr) || - clang::isa(sub_expr)) { - return Convert(sub_expr); - } + case clang::CastKind::CK_ArrayToPointerDecay: { // __va_list_tag [1] decays to __va_list_tag *. Just pass through by value if (IsVaListType(sub_expr->getType())) { Convert(sub_expr); break; } Convert(sub_expr); - if (sub_expr->getType().isConstQualified()) { - StrCat(keyword_ptr_decay_const_); + bool dest_pointee_const = + expr->getType()->getPointeeType().isConstQualified(); + if (clang::isa(sub_expr) || + clang::isa(sub_expr)) { + StrCat(".as_ptr()"); + if (!dest_pointee_const) { + StrCat(".cast_mut()"); + } } else { - StrCat(keyword_ptr_decay_); + StrCat(dest_pointee_const ? ".as_ptr()" : ".as_mut_ptr()"); } break; + } case clang::CastKind::CK_BitCast: { PushParen paren(*this); Convert(sub_expr); @@ -1756,6 +1775,21 @@ bool Converter::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) { } case clang::CastKind::CK_NoOp: { Convert(sub_expr); + if (expr->getType()->isPointerType() && + sub_expr->getType()->isPointerType() && + !clang::isa(expr->IgnoreImplicit())) { + switch (GetConstCastType(expr->getType()->getPointeeType(), + sub_expr->getType()->getPointeeType())) { + case ConstCastType::MutableToConst: + StrCat(".cast_const()"); + break; + case ConstCastType::ConstToMutable: + StrCat(".cast_mut()"); + break; + default: + break; + } + } break; } case clang::CastKind::CK_FunctionToPointerDecay: @@ -2949,9 +2983,8 @@ void Converter::ConvertVarInit(clang::QualType qual_type, clang::Expr *expr) { if (auto *lambda = clang::dyn_cast( expr->IgnoreUnlessSpelledInSource())) { PushExprKind push(*this, ExprKind::AddrOf); - curr_init_type_.push(qual_type); + PushInitType init_type(*this, qual_type); VisitLambdaExpr(lambda); - curr_init_type_.pop(); return; } } @@ -2968,21 +3001,18 @@ void Converter::ConvertVarInit(clang::QualType qual_type, clang::Expr *expr) { { PushParen paren(*this); StrCat(token::kStar); - curr_init_type_.push(qual_type); + PushInitType init_type(*this, qual_type); Convert(expr); - curr_init_type_.pop(); } StrCat(".clone()"); } else if (IsReferenceType(expr) || qual_type->isFunctionPointerType()) { PushExprKind push(*this, ExprKind::AddrOf); - curr_init_type_.push(qual_type); + PushInitType init_type(*this, qual_type); Convert(expr); - curr_init_type_.pop(); } else { PushExprKind push(*this, ExprKind::RValue); - curr_init_type_.push(qual_type); + PushInitType init_type(*this, qual_type); Convert(expr); - curr_init_type_.pop(); } if (qual_type->isReferenceType() && !IsReferenceType(expr)) { StrCat(keyword::kAs); @@ -3056,9 +3086,11 @@ void Converter::ConvertArraySubscript(clang::Expr *base, clang::Expr *idx, void Converter::ConvertAssignment(clang::Expr *lhs, clang::Expr *rhs, std::string_view assign_operator) { - curr_init_type_.push(lhs->getType()); - auto lhs_as_string = ConvertLValue(lhs); - curr_init_type_.pop(); + std::string lhs_as_string; + { + PushInitType init_type(*this, lhs->getType()); + lhs_as_string = ConvertLValue(lhs); + } auto rhs_as_string = ConvertFreshRValue(rhs); PushBrace brace(*this, !isVoid()); diff --git a/cpp2rust/converter/converter.h b/cpp2rust/converter/converter.h index 8e2fda4c..d98e2ad5 100644 --- a/cpp2rust/converter/converter.h +++ b/cpp2rust/converter/converter.h @@ -233,7 +233,7 @@ class Converter : public clang::RecursiveASTVisitor { std::string GetEscapedUTF8CharLiteral(clang::Expr *expr) const; std::string GetEscapedStringLiteral(clang::Expr *expr, - bool add_null_char = false) const; + uint64_t pad_nulls = 0) const; virtual bool VisitStringLiteral(clang::StringLiteral *expr); virtual bool VisitCXXBoolLiteralExpr(clang::CXXBoolLiteralExpr *expr); @@ -522,6 +522,19 @@ class Converter : public clang::RecursiveASTVisitor { std::stack &stack_; }; + class PushInitType { + public: + PushInitType(Converter &c, clang::QualType type) : c_(c) { + c_.curr_init_type_.push(type); + } + ~PushInitType() { c_.curr_init_type_.pop(); } + PushInitType(const PushInitType &) = delete; + PushInitType &operator=(const PushInitType &) = delete; + + private: + Converter &c_; + }; + std::unordered_set map_iter_decls_; struct ScopedMapIterDecl { diff --git a/cpp2rust/converter/converter_lib.cpp b/cpp2rust/converter/converter_lib.cpp index 40816ddf..6f6a537b 100644 --- a/cpp2rust/converter/converter_lib.cpp +++ b/cpp2rust/converter/converter_lib.cpp @@ -802,4 +802,16 @@ std::string ReplaceAll(std::string str, std::string_view from, return str; } +ConstCastType GetConstCastType(clang::QualType to, clang::QualType from) { + if (to.isConstQualified() && from.isConstQualified()) { + return ConstCastType::ConstToConst; + } else if (!to.isConstQualified() && from.isConstQualified()) { + return ConstCastType::ConstToMutable; + } else if (to.isConstQualified() && !from.isConstQualified()) { + return ConstCastType::MutableToConst; + } else { + return ConstCastType::MutableToMutable; + } +} + } // namespace cpp2rust diff --git a/cpp2rust/converter/converter_lib.h b/cpp2rust/converter/converter_lib.h index cef84d1a..2522980d 100644 --- a/cpp2rust/converter/converter_lib.h +++ b/cpp2rust/converter/converter_lib.h @@ -171,4 +171,13 @@ void Unwrap(std::string &s, std::string_view prefix, std::string_view suffix); std::string ReplaceAll(std::string str, std::string_view from, std::string_view to); +enum class ConstCastType { + ConstToConst, + ConstToMutable, + MutableToConst, + MutableToMutable, +}; + +ConstCastType GetConstCastType(clang::QualType to, clang::QualType from); + } // namespace cpp2rust diff --git a/cpp2rust/converter/models/converter_refcount.cpp b/cpp2rust/converter/models/converter_refcount.cpp index eedb1606..6f66b7fd 100644 --- a/cpp2rust/converter/models/converter_refcount.cpp +++ b/cpp2rust/converter/models/converter_refcount.cpp @@ -946,6 +946,22 @@ bool ConverterRefCount::VisitCallExpr(clang::CallExpr *expr) { } bool ConverterRefCount::VisitStringLiteral(clang::StringLiteral *expr) { + if (!curr_init_type_.empty() && curr_init_type_.top()->isArrayType()) { + uint64_t pad = 1; + if (auto *arr_ty = ctx_.getAsConstantArrayType(curr_init_type_.top())) { + uint64_t arr_size = arr_ty->getSize().getZExtValue(); + if (expr->getString().empty()) { + StrCat(std::format("vec![0u8; {}].into_boxed_slice()", arr_size)); + return false; + } + pad = arr_size > expr->getString().size() + ? arr_size - expr->getString().size() + : 0; + } + StrCat(std::format("Box::<[u8]>::from(b{}.as_slice())", + GetEscapedStringLiteral(expr, pad))); + return false; + } StrCat(GetEscapedStringLiteral(expr)); return false; } @@ -1035,6 +1051,11 @@ bool ConverterRefCount::VisitImplicitCastExpr(clang::ImplicitCastExpr *expr) { return false; } + if (expr->getCastKind() == clang::CastKind::CK_NoOp) { + Convert(sub_expr); + return false; + } + return Converter::VisitImplicitCastExpr(expr); } @@ -1656,6 +1677,7 @@ void ConverterRefCount::ConvertVarInit(clang::QualType qual_type, bool is_ref = qual_type->isReferenceType(); in_function_formals_ = true; PushConversionKind push(*this, ConversionKind::Unboxed, is_ref); + PushInitType init_type(*this, qual_type); StrCat(BoxValue((is_ref || qual_type->isFunctionPointerType()) ? ConvertFreshPointer(expr) : ConvertFreshRValue(expr))); diff --git a/rules/string/ir_unsafe.json b/rules/string/ir_unsafe.json index 2a903675..e863d85f 100644 --- a/rules/string/ir_unsafe.json +++ b/rules/string/ir_unsafe.json @@ -1548,13 +1548,13 @@ { "placeholder": { "arg": "a0", - "access": "read" + "access": "write" } } ], "body": [ { - "text": ".as_ptr()" + "text": ".as_mut_ptr()" } ] } @@ -1562,7 +1562,7 @@ ], "params": { "a0": { - "type": "Vec" + "type": "&mut Vec" } }, "return_type": { diff --git a/rules/string/tgt_unsafe.rs b/rules/string/tgt_unsafe.rs index a16cb743..4498dc9a 100644 --- a/rules/string/tgt_unsafe.rs +++ b/rules/string/tgt_unsafe.rs @@ -35,8 +35,8 @@ unsafe fn f4(a0: &mut Vec, a1: *mut u8, a2: usize) { unsafe fn f5(a0: Vec) -> *const u8 { a0.as_ptr() } -unsafe fn f6(a0: Vec) -> *const u8 { - a0.as_ptr() +unsafe fn f6(a0: &mut Vec) -> *const u8 { + a0.as_mut_ptr() } unsafe fn f7(a0: *const u8, a1: usize) -> Vec { std::slice::from_raw_parts(a0, a1 as usize) diff --git a/tests/unit/out/refcount/string_literals.rs b/tests/unit/out/refcount/string_literals.rs new file mode 100644 index 00000000..1cf23e03 --- /dev/null +++ b/tests/unit/out/refcount/string_literals.rs @@ -0,0 +1,63 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn foo_mut_0(str: Ptr) { + let str: Value> = Rc::new(RefCell::new(str)); +} +pub fn foo_const_1(str: Ptr) { + let str: Value> = Rc::new(RefCell::new(str)); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let immutable_strings: Value]>> = Rc::new(RefCell::new(Box::new([ + Ptr::from_string_literal("a"), + Ptr::from_string_literal("b"), + Ptr::from_string_literal("c"), + ]))); + let immutable_string: Value> = Rc::new(RefCell::new(Ptr::from_string_literal("hello"))); + let mutable_string_arr: Value> = + Rc::new(RefCell::new(Box::<[u8]>::from(b"papanasi\0".as_slice()))); + let immutable_string_arr: Value> = + Rc::new(RefCell::new(Box::<[u8]>::from(b"papanasi\0".as_slice()))); + let immutable_empty: Value> = Rc::new(RefCell::new(Ptr::from_string_literal(""))); + let mutable_empty_arr: Value> = + Rc::new(RefCell::new(vec![0u8; 1].into_boxed_slice())); + let immutable_empty_arr: Value> = + Rc::new(RefCell::new(vec![0u8; 1].into_boxed_slice())); + ({ + let _str: Ptr = (mutable_string_arr.as_pointer() as Ptr); + foo_mut_0(_str) + }); + ({ + let _str: Ptr = Ptr::from_string_literal("world"); + foo_const_1(_str) + }); + ({ + let _str: Ptr = (*immutable_string.borrow()).clone(); + foo_const_1(_str) + }); + ({ + let _str: Ptr = (immutable_string_arr.as_pointer() as Ptr); + foo_const_1(_str) + }); + ({ + let _str: Ptr = Ptr::from_string_literal(""); + foo_const_1(_str) + }); + ({ + let _str: Ptr = (*immutable_empty.borrow()).clone(); + foo_const_1(_str) + }); + ({ + let _str: Ptr = (immutable_empty_arr.as_pointer() as Ptr); + foo_const_1(_str) + }); + return 0; +} diff --git a/tests/unit/out/refcount/string_literals_c.rs b/tests/unit/out/refcount/string_literals_c.rs new file mode 100644 index 00000000..011caf2a --- /dev/null +++ b/tests/unit/out/refcount/string_literals_c.rs @@ -0,0 +1,94 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn foo_mut_0(str: Ptr) { + let str: Value> = Rc::new(RefCell::new(str)); +} +pub fn foo_const_1(str: Ptr) { + let str: Value> = Rc::new(RefCell::new(str)); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let mutable_strings: Value]>> = Rc::new(RefCell::new(Box::new([ + Ptr::from_string_literal("a"), + Ptr::from_string_literal("b"), + Ptr::from_string_literal("c"), + ]))); + let immutable_strings: Value]>> = Rc::new(RefCell::new(Box::new([ + Ptr::from_string_literal("a"), + Ptr::from_string_literal("b"), + Ptr::from_string_literal("c"), + ]))); + let mutable_string: Value> = Rc::new(RefCell::new(Ptr::from_string_literal("hello"))); + let immutable_string: Value> = Rc::new(RefCell::new(Ptr::from_string_literal("hello"))); + let mutable_string_arr: Value> = + Rc::new(RefCell::new(Box::<[u8]>::from(b"papanasi\0".as_slice()))); + let immutable_string_arr: Value> = + Rc::new(RefCell::new(Box::<[u8]>::from(b"papanasi\0".as_slice()))); + let mutable_empty: Value> = Rc::new(RefCell::new(Ptr::from_string_literal(""))); + let immutable_empty: Value> = Rc::new(RefCell::new(Ptr::from_string_literal(""))); + let mutable_empty_arr: Value> = + Rc::new(RefCell::new(vec![0u8; 1].into_boxed_slice())); + let immutable_empty_arr: Value> = + Rc::new(RefCell::new(vec![0u8; 1].into_boxed_slice())); + ({ + let _str: Ptr = Ptr::from_string_literal("world"); + foo_mut_0(_str) + }); + ({ + let _str: Ptr = (*mutable_string.borrow()).clone(); + foo_mut_0(_str) + }); + ({ + let _str: Ptr = (mutable_string_arr.as_pointer() as Ptr); + foo_mut_0(_str) + }); + ({ + let _str: Ptr = Ptr::from_string_literal("world"); + foo_const_1(_str) + }); + ({ + let _str: Ptr = (*mutable_string.borrow()).clone(); + foo_const_1(_str) + }); + ({ + let _str: Ptr = (*immutable_string.borrow()).clone(); + foo_const_1(_str) + }); + ({ + let _str: Ptr = (mutable_string_arr.as_pointer() as Ptr); + foo_const_1(_str) + }); + ({ + let _str: Ptr = (immutable_string_arr.as_pointer() as Ptr); + foo_const_1(_str) + }); + ({ + let _str: Ptr = Ptr::from_string_literal(""); + foo_const_1(_str) + }); + ({ + let _str: Ptr = (*mutable_empty.borrow()).clone(); + foo_const_1(_str) + }); + ({ + let _str: Ptr = (*immutable_empty.borrow()).clone(); + foo_const_1(_str) + }); + ({ + let _str: Ptr = (mutable_empty_arr.as_pointer() as Ptr); + foo_const_1(_str) + }); + ({ + let _str: Ptr = (immutable_empty_arr.as_pointer() as Ptr); + foo_const_1(_str) + }); + return 0; +} diff --git a/tests/unit/out/refcount/string_literals_concat.rs b/tests/unit/out/refcount/string_literals_concat.rs new file mode 100644 index 00000000..3bfeb994 --- /dev/null +++ b/tests/unit/out/refcount/string_literals_concat.rs @@ -0,0 +1,41 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let joined: Value> = Rc::new(RefCell::new(Ptr::from_string_literal( + "alpha\nbeta\ngamma\n", + ))); + assert!(((((*joined.borrow()).offset((0) as isize).read()) as i32) == (('a' as u8) as i32))); + assert!(((((*joined.borrow()).offset((5) as isize).read()) as i32) == (('\n' as u8) as i32))); + assert!(((((*joined.borrow()).offset((6) as isize).read()) as i32) == (('b' as u8) as i32))); + let arr: Value> = Rc::new(RefCell::new(Box::<[u8]>::from(b"foobar\0".as_slice()))); + assert!((((*arr.borrow())[(0) as usize] as i32) == (('f' as u8) as i32))); + assert!((((*arr.borrow())[(3) as usize] as i32) == (('b' as u8) as i32))); + assert!((((*arr.borrow())[(5) as usize] as i32) == (('r' as u8) as i32))); + assert!((((*arr.borrow())[(6) as usize] as i32) == (('\0' as u8) as i32))); + let split_pieces: Value> = Rc::new(RefCell::new(Ptr::from_string_literal("abcdefghi"))); + assert!( + ((((*split_pieces.borrow()).offset((0) as isize).read()) as i32) == (('a' as u8) as i32)) + ); + assert!( + ((((*split_pieces.borrow()).offset((3) as isize).read()) as i32) == (('d' as u8) as i32)) + ); + assert!( + ((((*split_pieces.borrow()).offset((6) as isize).read()) as i32) == (('g' as u8) as i32)) + ); + assert!( + ((((*split_pieces.borrow()).offset((8) as isize).read()) as i32) == (('i' as u8) as i32)) + ); + assert!( + ((((*split_pieces.borrow()).offset((9) as isize).read()) as i32) == (('\0' as u8) as i32)) + ); + return 0; +} diff --git a/tests/unit/out/refcount/string_literals_concat_c.rs b/tests/unit/out/refcount/string_literals_concat_c.rs new file mode 100644 index 00000000..1e59083a --- /dev/null +++ b/tests/unit/out/refcount/string_literals_concat_c.rs @@ -0,0 +1,25 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let arr: Value> = Rc::new(RefCell::new(Box::<[u8]>::from(b"foobar\0".as_slice()))); + assert!((((*arr.borrow())[(0) as usize] as i32) == ('f' as i32))); + assert!((((*arr.borrow())[(3) as usize] as i32) == ('b' as i32))); + assert!((((*arr.borrow())[(5) as usize] as i32) == ('r' as i32))); + assert!((((*arr.borrow())[(6) as usize] as i32) == ('\0' as i32))); + let split_pieces: Value> = Rc::new(RefCell::new(Ptr::from_string_literal("abcdefghi"))); + assert!(((((*split_pieces.borrow()).offset((0) as isize).read()) as i32) == ('a' as i32))); + assert!(((((*split_pieces.borrow()).offset((3) as isize).read()) as i32) == ('d' as i32))); + assert!(((((*split_pieces.borrow()).offset((6) as isize).read()) as i32) == ('g' as i32))); + assert!(((((*split_pieces.borrow()).offset((8) as isize).read()) as i32) == ('i' as i32))); + assert!(((((*split_pieces.borrow()).offset((9) as isize).read()) as i32) == ('\0' as i32))); + return 0; +} diff --git a/tests/unit/out/refcount/string_literals_return.rs b/tests/unit/out/refcount/string_literals_return.rs new file mode 100644 index 00000000..506ba96c --- /dev/null +++ b/tests/unit/out/refcount/string_literals_return.rs @@ -0,0 +1,51 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn get_greeting_0() -> Ptr { + return Ptr::from_string_literal("hello"); +} +pub fn get_empty_1() -> Ptr { + return Ptr::from_string_literal(""); +} +pub fn get_branch_2(x: i32) -> Ptr { + let x: Value = Rc::new(RefCell::new(x)); + if ((*x.borrow()) > 0) { + return Ptr::from_string_literal("positive"); + } + return Ptr::from_string_literal("non-positive"); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let a: Value> = Rc::new(RefCell::new(({ get_greeting_0() }))); + assert!(((((*a.borrow()).offset((0) as isize).read()) as i32) == (('h' as u8) as i32))); + assert!(((((*a.borrow()).offset((4) as isize).read()) as i32) == (('o' as u8) as i32))); + assert!(((((*a.borrow()).offset((5) as isize).read()) as i32) == (('\0' as u8) as i32))); + let b: Value> = Rc::new(RefCell::new(({ get_empty_1() }))); + assert!(((((*b.borrow()).offset((0) as isize).read()) as i32) == (('\0' as u8) as i32))); + let c: Value> = Rc::new(RefCell::new( + ({ + let _x: i32 = 1; + get_branch_2(_x) + }), + )); + assert!(((((*c.borrow()).offset((0) as isize).read()) as i32) == (('p' as u8) as i32))); + assert!(((((*c.borrow()).offset((7) as isize).read()) as i32) == (('e' as u8) as i32))); + assert!(((((*c.borrow()).offset((8) as isize).read()) as i32) == (('\0' as u8) as i32))); + let d: Value> = Rc::new(RefCell::new( + ({ + let _x: i32 = -1_i32; + get_branch_2(_x) + }), + )); + assert!(((((*d.borrow()).offset((0) as isize).read()) as i32) == (('n' as u8) as i32))); + assert!(((((*d.borrow()).offset((11) as isize).read()) as i32) == (('e' as u8) as i32))); + assert!(((((*d.borrow()).offset((12) as isize).read()) as i32) == (('\0' as u8) as i32))); + return 0; +} diff --git a/tests/unit/out/refcount/string_literals_return_c.rs b/tests/unit/out/refcount/string_literals_return_c.rs new file mode 100644 index 00000000..809b731b --- /dev/null +++ b/tests/unit/out/refcount/string_literals_return_c.rs @@ -0,0 +1,51 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn get_greeting_0() -> Ptr { + return Ptr::from_string_literal("hello"); +} +pub fn get_empty_1() -> Ptr { + return Ptr::from_string_literal(""); +} +pub fn get_branch_2(x: i32) -> Ptr { + let x: Value = Rc::new(RefCell::new(x)); + if ((*x.borrow()) > 0) { + return Ptr::from_string_literal("positive"); + } + return Ptr::from_string_literal("non-positive"); +} +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let a: Value> = Rc::new(RefCell::new(({ get_greeting_0() }))); + assert!(((((*a.borrow()).offset((0) as isize).read()) as i32) == ('h' as i32))); + assert!(((((*a.borrow()).offset((4) as isize).read()) as i32) == ('o' as i32))); + assert!(((((*a.borrow()).offset((5) as isize).read()) as i32) == ('\0' as i32))); + let b: Value> = Rc::new(RefCell::new(({ get_empty_1() }))); + assert!(((((*b.borrow()).offset((0) as isize).read()) as i32) == ('\0' as i32))); + let c: Value> = Rc::new(RefCell::new( + ({ + let _x: i32 = 1; + get_branch_2(_x) + }), + )); + assert!(((((*c.borrow()).offset((0) as isize).read()) as i32) == ('p' as i32))); + assert!(((((*c.borrow()).offset((7) as isize).read()) as i32) == ('e' as i32))); + assert!(((((*c.borrow()).offset((8) as isize).read()) as i32) == ('\0' as i32))); + let d: Value> = Rc::new(RefCell::new( + ({ + let _x: i32 = -1_i32; + get_branch_2(_x) + }), + )); + assert!(((((*d.borrow()).offset((0) as isize).read()) as i32) == ('n' as i32))); + assert!(((((*d.borrow()).offset((11) as isize).read()) as i32) == ('e' as i32))); + assert!(((((*d.borrow()).offset((12) as isize).read()) as i32) == ('\0' as i32))); + return 0; +} diff --git a/tests/unit/out/refcount/string_literals_sized.rs b/tests/unit/out/refcount/string_literals_sized.rs new file mode 100644 index 00000000..9cb9f05c --- /dev/null +++ b/tests/unit/out/refcount/string_literals_sized.rs @@ -0,0 +1,39 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let empty_buf: Value> = Rc::new(RefCell::new(vec![0u8; 256].into_boxed_slice())); + assert!((((*empty_buf.borrow())[(0) as usize] as i32) == (('\0' as u8) as i32))); + assert!((((*empty_buf.borrow())[(255) as usize] as i32) == (('\0' as u8) as i32))); + let prefix_buf: Value> = Rc::new(RefCell::new(Box::<[u8]>::from( + b"%\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0".as_slice(), + ))); + assert!((((*prefix_buf.borrow())[(0) as usize] as i32) == (('%' as u8) as i32))); + assert!((((*prefix_buf.borrow())[(1) as usize] as i32) == (('\0' as u8) as i32))); + assert!((((*prefix_buf.borrow())[(31) as usize] as i32) == (('\0' as u8) as i32))); + let short_buf: Value> = Rc::new(RefCell::new(Box::<[u8]>::from( + b"hi\0\0\0\0\0\0\0\0\0\0\0\0\0\0".as_slice(), + ))); + assert!((((*short_buf.borrow())[(0) as usize] as i32) == (('h' as u8) as i32))); + assert!((((*short_buf.borrow())[(1) as usize] as i32) == (('i' as u8) as i32))); + assert!((((*short_buf.borrow())[(2) as usize] as i32) == (('\0' as u8) as i32))); + assert!((((*short_buf.borrow())[(15) as usize] as i32) == (('\0' as u8) as i32))); + let exact_buf: Value> = + Rc::new(RefCell::new(Box::<[u8]>::from(b"hello\0".as_slice()))); + assert!((((*exact_buf.borrow())[(0) as usize] as i32) == (('h' as u8) as i32))); + assert!((((*exact_buf.borrow())[(4) as usize] as i32) == (('o' as u8) as i32))); + assert!((((*exact_buf.borrow())[(5) as usize] as i32) == (('\0' as u8) as i32))); + assert!((::std::mem::size_of::<[u8; 6]>() as u64 == 6_u64)); + assert!(((::std::mem::size_of::<[u8; 6]>() as u64 as u64).wrapping_sub(1_u64) == 5_u64)); + assert!((::std::mem::size_of::<[u8; 1]>() as u64 == 1_u64)); + assert!(((::std::mem::size_of::<[u8; 16]>() as u64 as u64).wrapping_sub(1_u64) == 15_u64)); + return 0; +} diff --git a/tests/unit/out/refcount/string_literals_sized_c.rs b/tests/unit/out/refcount/string_literals_sized_c.rs new file mode 100644 index 00000000..fd1ce120 --- /dev/null +++ b/tests/unit/out/refcount/string_literals_sized_c.rs @@ -0,0 +1,39 @@ +extern crate libcc2rs; +use libcc2rs::*; +use std::cell::RefCell; +use std::collections::BTreeMap; +use std::io::prelude::*; +use std::io::{Read, Seek, Write}; +use std::os::fd::AsFd; +use std::rc::{Rc, Weak}; +pub fn main() { + std::process::exit(main_0()); +} +fn main_0() -> i32 { + let empty_buf: Value> = Rc::new(RefCell::new(vec![0u8; 256].into_boxed_slice())); + assert!((((*empty_buf.borrow())[(0) as usize] as i32) == ('\0' as i32))); + assert!((((*empty_buf.borrow())[(255) as usize] as i32) == ('\0' as i32))); + let prefix_buf: Value> = Rc::new(RefCell::new(Box::<[u8]>::from( + b"%\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0".as_slice(), + ))); + assert!((((*prefix_buf.borrow())[(0) as usize] as i32) == ('%' as i32))); + assert!((((*prefix_buf.borrow())[(1) as usize] as i32) == ('\0' as i32))); + assert!((((*prefix_buf.borrow())[(31) as usize] as i32) == ('\0' as i32))); + let short_buf: Value> = Rc::new(RefCell::new(Box::<[u8]>::from( + b"hi\0\0\0\0\0\0\0\0\0\0\0\0\0\0".as_slice(), + ))); + assert!((((*short_buf.borrow())[(0) as usize] as i32) == ('h' as i32))); + assert!((((*short_buf.borrow())[(1) as usize] as i32) == ('i' as i32))); + assert!((((*short_buf.borrow())[(2) as usize] as i32) == ('\0' as i32))); + assert!((((*short_buf.borrow())[(15) as usize] as i32) == ('\0' as i32))); + let exact_buf: Value> = + Rc::new(RefCell::new(Box::<[u8]>::from(b"hello\0".as_slice()))); + assert!((((*exact_buf.borrow())[(0) as usize] as i32) == ('h' as i32))); + assert!((((*exact_buf.borrow())[(4) as usize] as i32) == ('o' as i32))); + assert!((((*exact_buf.borrow())[(5) as usize] as i32) == ('\0' as i32))); + assert!((::std::mem::size_of::<[u8; 6]>() as u64 == 6_u64)); + assert!(((::std::mem::size_of::<[u8; 6]>() as u64 as u64).wrapping_sub(1_u64) == 5_u64)); + assert!((::std::mem::size_of::<[u8; 1]>() as u64 == 1_u64)); + assert!(((::std::mem::size_of::<[u8; 16]>() as u64 as u64).wrapping_sub(1_u64) == 15_u64)); + return 0; +} diff --git a/tests/unit/out/unsafe/borrow_mut_opt.rs b/tests/unit/out/unsafe/borrow_mut_opt.rs index 14ee319e..9f53ea00 100644 --- a/tests/unit/out/unsafe/borrow_mut_opt.rs +++ b/tests/unit/out/unsafe/borrow_mut_opt.rs @@ -23,7 +23,7 @@ pub unsafe fn convert_without_rhs_0() { let mut w: i32 = ((arr[(y) as usize]) + (arr[(x) as usize])); w += (((z) + (y)) + (x)); let mut arr2: [u8; 3] = [('a' as u8), ('b' as u8), ('c' as u8)]; - let mut p1: *const i32 = (&mut x as *mut i32); + let mut p1: *const i32 = (&mut x as *mut i32).cast_const(); let mut c: u8 = arr2[(*p1) as usize]; c = arr2[(*p1) as usize]; let mut p2: *mut i32 = (&mut x as *mut i32); diff --git a/tests/unit/out/unsafe/huffman.rs b/tests/unit/out/unsafe/huffman.rs index d9da3862..868c697e 100644 --- a/tests/unit/out/unsafe/huffman.rs +++ b/tests/unit/out/unsafe/huffman.rs @@ -241,7 +241,7 @@ pub unsafe fn CollectCodes_4( CollectCodes_4(_root, _arr, _top, _out, _next) }); } - if (unsafe { (*root).IsLeaf() }) { + if (unsafe { (*root.cast_const()).IsLeaf() }) { (unsafe { let _arr: *mut Option> = arr; let _top: i32 = top; diff --git a/tests/unit/out/unsafe/main.rs b/tests/unit/out/unsafe/main.rs index d59202ca..3114a94a 100644 --- a/tests/unit/out/unsafe/main.rs +++ b/tests/unit/out/unsafe/main.rs @@ -18,7 +18,7 @@ pub fn main() { } unsafe fn main_0(mut argc: i32, mut argv: *mut *mut u8) -> i32 { let mut s: Vec = { - let s = (*argv.offset((0) as isize)); + let s = (*argv.offset((0) as isize)).cast_const(); std::slice::from_raw_parts(s, (0..).take_while(|&i| *s.add(i) != 0).count() + 1).to_vec() }; assert!(((argc) == (1))); diff --git a/tests/unit/out/unsafe/pointer_diff.rs b/tests/unit/out/unsafe/pointer_diff.rs index 45b0bd2a..794fdc58 100644 --- a/tests/unit/out/unsafe/pointer_diff.rs +++ b/tests/unit/out/unsafe/pointer_diff.rs @@ -13,7 +13,7 @@ pub fn main() { } unsafe fn main_0() -> i32 { let mut a: [i32; 5] = [1, 2, 3, 4, 5]; - let mut p0: *const i32 = (&mut a[(0) as usize] as *mut i32); - let mut p1: *const i32 = (&mut a[(4) as usize] as *mut i32); + let mut p0: *const i32 = (&mut a[(0) as usize] as *mut i32).cast_const(); + let mut p1: *const i32 = (&mut a[(4) as usize] as *mut i32).cast_const(); return ((((p1 as usize - p0 as usize) / ::std::mem::size_of::()) as u64) as i32); } diff --git a/tests/unit/out/unsafe/pointer_eq.rs b/tests/unit/out/unsafe/pointer_eq.rs index e2ce1241..94d7ce53 100644 --- a/tests/unit/out/unsafe/pointer_eq.rs +++ b/tests/unit/out/unsafe/pointer_eq.rs @@ -13,11 +13,11 @@ pub fn main() { } unsafe fn main_0() -> i32 { let mut x: i32 = 5; - let mut p1: *const i32 = (&mut x as *mut i32); - let mut p2: *const i32 = (&mut x as *mut i32); + let mut p1: *const i32 = (&mut x as *mut i32).cast_const(); + let mut p2: *const i32 = (&mut x as *mut i32).cast_const(); assert!(((p1) == (p2))); let mut y: i32 = 5; - let mut p3: *const i32 = (&mut y as *mut i32); + let mut p3: *const i32 = (&mut y as *mut i32).cast_const(); assert!(((p1) != (p3))); let mut arr: [i32; 3] = [1, 2, 3]; let mut p: *mut i32 = arr.as_mut_ptr(); diff --git a/tests/unit/out/unsafe/pointer_neq.rs b/tests/unit/out/unsafe/pointer_neq.rs index 7937b5c8..a3c972ce 100644 --- a/tests/unit/out/unsafe/pointer_neq.rs +++ b/tests/unit/out/unsafe/pointer_neq.rs @@ -13,8 +13,8 @@ pub fn main() { } unsafe fn main_0() -> i32 { let mut x: i32 = 5; - let mut p1: *const i32 = (&mut x as *mut i32); - let mut p2: *const i32 = (&mut x as *mut i32); + let mut p1: *const i32 = (&mut x as *mut i32).cast_const(); + let mut p2: *const i32 = (&mut x as *mut i32).cast_const(); if ((p1) != (p2)) { return 1; } else { diff --git a/tests/unit/out/unsafe/pointer_offset.rs b/tests/unit/out/unsafe/pointer_offset.rs index 34bf0329..e2c76091 100644 --- a/tests/unit/out/unsafe/pointer_offset.rs +++ b/tests/unit/out/unsafe/pointer_offset.rs @@ -14,7 +14,7 @@ pub fn main() { unsafe fn main_0() -> i32 { let mut out: i32 = 0; let mut arr: [i32; 5] = [1, 2, 3, 4, 0]; - let mut ptr: *const i32 = (&mut arr[(0) as usize] as *mut i32); + let mut ptr: *const i32 = (&mut arr[(0) as usize] as *mut i32).cast_const(); 'loop_: while ((*ptr) != (0)) { out += (*ptr); ptr.prefix_inc(); @@ -29,7 +29,7 @@ unsafe fn main_0() -> i32 { out += (*ptr); ptr.postfix_dec(); } - let mut ptr: *const i32 = (&mut arr[(3) as usize] as *mut i32); + let mut ptr: *const i32 = (&mut arr[(3) as usize] as *mut i32).cast_const(); 'loop_: while ((*ptr) != (2)) { out += (*ptr); ptr.prefix_dec(); diff --git a/tests/unit/out/unsafe/polymorphism.rs b/tests/unit/out/unsafe/polymorphism.rs index 3152dceb..2f98f685 100644 --- a/tests/unit/out/unsafe/polymorphism.rs +++ b/tests/unit/out/unsafe/polymorphism.rs @@ -38,9 +38,9 @@ pub fn main() { unsafe fn main_0() -> i32 { let mut dog: Dog = ::default(); let mut animal: *mut dyn Animal = (&mut dog as *mut Dog); - let mut eat1: bool = (unsafe { (*animal).bark() }); + let mut eat1: bool = (unsafe { (*animal.cast_const()).bark() }); let mut cat: Cat = ::default(); animal = (&mut cat as *mut Cat); - let mut eat2: bool = (unsafe { (*animal).bark() }); + let mut eat2: bool = (unsafe { (*animal.cast_const()).bark() }); return (((eat1) && (!eat2)) as i32); } diff --git a/tests/unit/out/unsafe/printfs.rs b/tests/unit/out/unsafe/printfs.rs index 5933ebb7..9e3e799f 100644 --- a/tests/unit/out/unsafe/printfs.rs +++ b/tests/unit/out/unsafe/printfs.rs @@ -40,7 +40,7 @@ unsafe fn main_0() -> i32 { let s = b"a string\0".as_ptr(); std::slice::from_raw_parts(s, (0..).take_while(|&i| *s.add(i) != 0).count() + 1).to_vec() }; - printf(b"%s\n\0".as_ptr() as *const i8, s.as_ptr()); + printf(b"%s\n\0".as_ptr() as *const i8, s.as_mut_ptr()); printf( b"%s\n\0".as_ptr() as *const i8, (unsafe { diff --git a/tests/unit/out/unsafe/refs_as_args.rs b/tests/unit/out/unsafe/refs_as_args.rs index cbb7a05b..656b163a 100644 --- a/tests/unit/out/unsafe/refs_as_args.rs +++ b/tests/unit/out/unsafe/refs_as_args.rs @@ -9,7 +9,7 @@ use std::rc::Rc; pub unsafe fn more_refs_0(mut x1: i32, mut x2: i32, r1: *mut i32, r2: *const i32) { let rx1: *const i32 = &x1 as *const i32; let rx2: *mut i32 = &mut x2 as *mut i32; - let mut pr1: *const i32 = (r1); + let mut pr1: *const i32 = (r1).cast_const(); let mut pr2: *const i32 = (r2); let rpr1: *const i32 = &(*pr1) as *const i32; let rpr2: *const i32 = &(*pr2) as *const i32; diff --git a/tests/unit/out/unsafe/string.rs b/tests/unit/out/unsafe/string.rs index 79044a77..6162f3dc 100644 --- a/tests/unit/out/unsafe/string.rs +++ b/tests/unit/out/unsafe/string.rs @@ -30,7 +30,7 @@ unsafe fn main_0() -> i32 { .to_vec() } ); - let mut p1: *const u8 = s1.as_ptr(); + let mut p1: *const u8 = s1.as_mut_ptr().cast_const(); assert!((((*p1.offset((0) as isize)) as i32) == (('h' as u8) as i32))); assert!((((*p1.offset((1) as isize)) as i32) == (('e' as u8) as i32))); assert!((((*p1.offset((2) as isize)) as i32) == (('l' as u8) as i32))); @@ -41,7 +41,7 @@ unsafe fn main_0() -> i32 { .cloned() .chain(std::iter::once(0)) .collect(); - let mut p2: *const u8 = s2.as_ptr(); + let mut p2: *const u8 = s2.as_mut_ptr().cast_const(); let mut i: u32 = 0_u32; 'loop_: while ((i as u64) < ((s2.len() - 1) as u64)) { assert!( @@ -72,7 +72,7 @@ unsafe fn main_0() -> i32 { }; assert!((((s3.len() - 1) as u64) == (5_u64))); assert!((((s3.len() - 1) as u64) == ((s3.len() - 1) as u64))); - let mut p3: *const u8 = s3.as_ptr(); + let mut p3: *const u8 = s3.as_mut_ptr().cast_const(); let mut i: u32 = 0_u32; 'loop_: while ((i as u64) < ((s3.len() - 1) as u64)) { assert!((((*p3.offset((i) as isize)) as i32) == (s3[(i as u64) as usize] as i32))); @@ -99,7 +99,7 @@ unsafe fn main_0() -> i32 { }; assert!((((s4.len() - 1) as u64) == (3_u64))); assert!((((s4.len() - 1) as u64) == ((s4.len() - 1) as u64))); - let mut p4: *const u8 = s4.as_ptr(); + let mut p4: *const u8 = s4.as_mut_ptr().cast_const(); let mut i: u32 = 0_u32; 'loop_: while ((i as u64) < ((s4.len() - 1) as u64)) { assert!((((*p4.offset((i) as isize)) as i32) == (s4[(i as u64) as usize] as i32))); @@ -118,7 +118,7 @@ unsafe fn main_0() -> i32 { }; assert!((((s5.len() - 1) as u64) == (12_u64))); assert!((((s5.len() - 1) as u64) == ((s5.len() - 1) as u64))); - let mut p5: *const u8 = s5.as_ptr(); + let mut p5: *const u8 = s5.as_mut_ptr().cast_const(); let mut i: u32 = 0_u32; 'loop_: while ((i as u64) < ((s5.len() - 1) as u64)) { assert!((((*p5.offset((i) as isize)) as i32) == (s5[(i as u64) as usize] as i32))); @@ -133,12 +133,13 @@ unsafe fn main_0() -> i32 { ('o' as u8), ('o' as u8), ]; - let mut string: Vec = std::slice::from_raw_parts(arr.as_mut_ptr(), 3_u64 as usize) - .to_vec() - .iter() - .copied() - .chain(std::iter::once(0)) - .collect(); + let mut string: Vec = + std::slice::from_raw_parts(arr.as_mut_ptr().cast_const(), 3_u64 as usize) + .to_vec() + .iter() + .copied() + .chain(std::iter::once(0)) + .collect(); assert!((((string.len() - 1) as u64) == (3_u64))); assert!(((string[(0_u64) as usize] as i32) == (('b' as u8) as i32))); assert!(((string[(1_u64) as usize] as i32) == (('a' as u8) as i32))); diff --git a/tests/unit/out/unsafe/string_literals.rs b/tests/unit/out/unsafe/string_literals.rs new file mode 100644 index 00000000..4ee5d517 --- /dev/null +++ b/tests/unit/out/unsafe/string_literals.rs @@ -0,0 +1,53 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub unsafe fn foo_mut_0(mut str: *mut u8) {} +pub unsafe fn foo_const_1(mut str: *const u8) {} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut immutable_strings: [*const u8; 3] = [b"a\0".as_ptr(), b"b\0".as_ptr(), b"c\0".as_ptr()]; + let mut immutable_string: *const u8 = b"hello\0".as_ptr(); + let mut mutable_string_arr: [u8; 9] = *b"papanasi\0"; + let immutable_string_arr: [u8; 9] = *b"papanasi\0"; + let mut immutable_empty: *const u8 = b"\0".as_ptr(); + let mut mutable_empty_arr: [u8; 1] = [0u8; 1]; + let immutable_empty_arr: [u8; 1] = [0u8; 1]; + (unsafe { + let _str: *mut u8 = mutable_string_arr.as_mut_ptr(); + foo_mut_0(_str) + }); + (unsafe { + let _str: *const u8 = b"world\0".as_ptr(); + foo_const_1(_str) + }); + (unsafe { + let _str: *const u8 = immutable_string; + foo_const_1(_str) + }); + (unsafe { + let _str: *const u8 = immutable_string_arr.as_ptr(); + foo_const_1(_str) + }); + (unsafe { + let _str: *const u8 = b"\0".as_ptr(); + foo_const_1(_str) + }); + (unsafe { + let _str: *const u8 = immutable_empty; + foo_const_1(_str) + }); + (unsafe { + let _str: *const u8 = immutable_empty_arr.as_ptr(); + foo_const_1(_str) + }); + return 0; +} diff --git a/tests/unit/out/unsafe/string_literals_c.rs b/tests/unit/out/unsafe/string_literals_c.rs new file mode 100644 index 00000000..2f0d7ea7 --- /dev/null +++ b/tests/unit/out/unsafe/string_literals_c.rs @@ -0,0 +1,88 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub unsafe fn foo_mut_0(mut str: *mut u8) {} +pub unsafe fn foo_const_1(mut str: *const u8) {} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut mutable_strings: [*mut u8; 3] = [ + b"a\0".as_ptr().cast_mut(), + b"b\0".as_ptr().cast_mut(), + b"c\0".as_ptr().cast_mut(), + ]; + let mut immutable_strings: [*const u8; 3] = [ + b"a\0".as_ptr().cast_mut().cast_const(), + b"b\0".as_ptr().cast_mut().cast_const(), + b"c\0".as_ptr().cast_mut().cast_const(), + ]; + let mut mutable_string: *mut u8 = b"hello\0".as_ptr().cast_mut(); + let mut immutable_string: *const u8 = b"hello\0".as_ptr().cast_mut().cast_const(); + let mut mutable_string_arr: [u8; 9] = *b"papanasi\0"; + let immutable_string_arr: [u8; 9] = *b"papanasi\0"; + let mut mutable_empty: *mut u8 = b"\0".as_ptr().cast_mut(); + let mut immutable_empty: *const u8 = b"\0".as_ptr().cast_mut().cast_const(); + let mut mutable_empty_arr: [u8; 1] = [0u8; 1]; + let immutable_empty_arr: [u8; 1] = [0u8; 1]; + (unsafe { + let _str: *mut u8 = b"world\0".as_ptr().cast_mut(); + foo_mut_0(_str) + }); + (unsafe { + let _str: *mut u8 = mutable_string; + foo_mut_0(_str) + }); + (unsafe { + let _str: *mut u8 = mutable_string_arr.as_mut_ptr(); + foo_mut_0(_str) + }); + (unsafe { + let _str: *const u8 = b"world\0".as_ptr().cast_mut().cast_const(); + foo_const_1(_str) + }); + (unsafe { + let _str: *const u8 = mutable_string.cast_const(); + foo_const_1(_str) + }); + (unsafe { + let _str: *const u8 = immutable_string; + foo_const_1(_str) + }); + (unsafe { + let _str: *const u8 = mutable_string_arr.as_mut_ptr().cast_const(); + foo_const_1(_str) + }); + (unsafe { + let _str: *const u8 = immutable_string_arr.as_ptr(); + foo_const_1(_str) + }); + (unsafe { + let _str: *const u8 = b"\0".as_ptr().cast_mut().cast_const(); + foo_const_1(_str) + }); + (unsafe { + let _str: *const u8 = mutable_empty.cast_const(); + foo_const_1(_str) + }); + (unsafe { + let _str: *const u8 = immutable_empty; + foo_const_1(_str) + }); + (unsafe { + let _str: *const u8 = mutable_empty_arr.as_mut_ptr().cast_const(); + foo_const_1(_str) + }); + (unsafe { + let _str: *const u8 = immutable_empty_arr.as_ptr(); + foo_const_1(_str) + }); + return 0; +} diff --git a/tests/unit/out/unsafe/string_literals_concat.rs b/tests/unit/out/unsafe/string_literals_concat.rs new file mode 100644 index 00000000..ce35fafb --- /dev/null +++ b/tests/unit/out/unsafe/string_literals_concat.rs @@ -0,0 +1,31 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut joined: *const u8 = b"alpha\nbeta\ngamma\n\0".as_ptr(); + assert!((((*joined.offset((0) as isize)) as i32) == (('a' as u8) as i32))); + assert!((((*joined.offset((5) as isize)) as i32) == (('\n' as u8) as i32))); + assert!((((*joined.offset((6) as isize)) as i32) == (('b' as u8) as i32))); + let mut arr: [u8; 7] = *b"foobar\0"; + assert!(((arr[(0) as usize] as i32) == (('f' as u8) as i32))); + assert!(((arr[(3) as usize] as i32) == (('b' as u8) as i32))); + assert!(((arr[(5) as usize] as i32) == (('r' as u8) as i32))); + assert!(((arr[(6) as usize] as i32) == (('\0' as u8) as i32))); + let mut split_pieces: *const u8 = b"abcdefghi\0".as_ptr(); + assert!((((*split_pieces.offset((0) as isize)) as i32) == (('a' as u8) as i32))); + assert!((((*split_pieces.offset((3) as isize)) as i32) == (('d' as u8) as i32))); + assert!((((*split_pieces.offset((6) as isize)) as i32) == (('g' as u8) as i32))); + assert!((((*split_pieces.offset((8) as isize)) as i32) == (('i' as u8) as i32))); + assert!((((*split_pieces.offset((9) as isize)) as i32) == (('\0' as u8) as i32))); + return 0; +} diff --git a/tests/unit/out/unsafe/string_literals_concat_c.rs b/tests/unit/out/unsafe/string_literals_concat_c.rs new file mode 100644 index 00000000..e12cb8c1 --- /dev/null +++ b/tests/unit/out/unsafe/string_literals_concat_c.rs @@ -0,0 +1,27 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut arr: [u8; 7] = *b"foobar\0"; + assert!(((arr[(0) as usize] as i32) == ('f' as i32))); + assert!(((arr[(3) as usize] as i32) == ('b' as i32))); + assert!(((arr[(5) as usize] as i32) == ('r' as i32))); + assert!(((arr[(6) as usize] as i32) == ('\0' as i32))); + let mut split_pieces: *const u8 = b"abcdefghi\0".as_ptr().cast_mut().cast_const(); + assert!((((*split_pieces.offset((0) as isize)) as i32) == ('a' as i32))); + assert!((((*split_pieces.offset((3) as isize)) as i32) == ('d' as i32))); + assert!((((*split_pieces.offset((6) as isize)) as i32) == ('g' as i32))); + assert!((((*split_pieces.offset((8) as isize)) as i32) == ('i' as i32))); + assert!((((*split_pieces.offset((9) as isize)) as i32) == ('\0' as i32))); + return 0; +} diff --git a/tests/unit/out/unsafe/string_literals_return.rs b/tests/unit/out/unsafe/string_literals_return.rs new file mode 100644 index 00000000..06d1d65e --- /dev/null +++ b/tests/unit/out/unsafe/string_literals_return.rs @@ -0,0 +1,48 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub unsafe fn get_greeting_0() -> *const u8 { + return b"hello\0".as_ptr(); +} +pub unsafe fn get_empty_1() -> *const u8 { + return b"\0".as_ptr(); +} +pub unsafe fn get_branch_2(mut x: i32) -> *const u8 { + if ((x) > (0)) { + return b"positive\0".as_ptr(); + } + return b"non-positive\0".as_ptr(); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut a: *const u8 = (unsafe { get_greeting_0() }); + assert!((((*a.offset((0) as isize)) as i32) == (('h' as u8) as i32))); + assert!((((*a.offset((4) as isize)) as i32) == (('o' as u8) as i32))); + assert!((((*a.offset((5) as isize)) as i32) == (('\0' as u8) as i32))); + let mut b: *const u8 = (unsafe { get_empty_1() }); + assert!((((*b.offset((0) as isize)) as i32) == (('\0' as u8) as i32))); + let mut c: *const u8 = (unsafe { + let _x: i32 = 1; + get_branch_2(_x) + }); + assert!((((*c.offset((0) as isize)) as i32) == (('p' as u8) as i32))); + assert!((((*c.offset((7) as isize)) as i32) == (('e' as u8) as i32))); + assert!((((*c.offset((8) as isize)) as i32) == (('\0' as u8) as i32))); + let mut d: *const u8 = (unsafe { + let _x: i32 = -1_i32; + get_branch_2(_x) + }); + assert!((((*d.offset((0) as isize)) as i32) == (('n' as u8) as i32))); + assert!((((*d.offset((11) as isize)) as i32) == (('e' as u8) as i32))); + assert!((((*d.offset((12) as isize)) as i32) == (('\0' as u8) as i32))); + return 0; +} diff --git a/tests/unit/out/unsafe/string_literals_return_c.rs b/tests/unit/out/unsafe/string_literals_return_c.rs new file mode 100644 index 00000000..82cded37 --- /dev/null +++ b/tests/unit/out/unsafe/string_literals_return_c.rs @@ -0,0 +1,48 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub unsafe fn get_greeting_0() -> *const u8 { + return b"hello\0".as_ptr().cast_mut().cast_const(); +} +pub unsafe fn get_empty_1() -> *const u8 { + return b"\0".as_ptr().cast_mut().cast_const(); +} +pub unsafe fn get_branch_2(mut x: i32) -> *const u8 { + if ((x) > (0)) { + return b"positive\0".as_ptr().cast_mut().cast_const(); + } + return b"non-positive\0".as_ptr().cast_mut().cast_const(); +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut a: *const u8 = (unsafe { get_greeting_0() }); + assert!((((*a.offset((0) as isize)) as i32) == ('h' as i32))); + assert!((((*a.offset((4) as isize)) as i32) == ('o' as i32))); + assert!((((*a.offset((5) as isize)) as i32) == ('\0' as i32))); + let mut b: *const u8 = (unsafe { get_empty_1() }); + assert!((((*b.offset((0) as isize)) as i32) == ('\0' as i32))); + let mut c: *const u8 = (unsafe { + let _x: i32 = 1; + get_branch_2(_x) + }); + assert!((((*c.offset((0) as isize)) as i32) == ('p' as i32))); + assert!((((*c.offset((7) as isize)) as i32) == ('e' as i32))); + assert!((((*c.offset((8) as isize)) as i32) == ('\0' as i32))); + let mut d: *const u8 = (unsafe { + let _x: i32 = -1_i32; + get_branch_2(_x) + }); + assert!((((*d.offset((0) as isize)) as i32) == ('n' as i32))); + assert!((((*d.offset((11) as isize)) as i32) == ('e' as i32))); + assert!((((*d.offset((12) as isize)) as i32) == ('\0' as i32))); + return 0; +} diff --git a/tests/unit/out/unsafe/string_literals_sized.rs b/tests/unit/out/unsafe/string_literals_sized.rs new file mode 100644 index 00000000..4326ba49 --- /dev/null +++ b/tests/unit/out/unsafe/string_literals_sized.rs @@ -0,0 +1,37 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut empty_buf: [u8; 256] = [0u8; 256]; + assert!(((empty_buf[(0) as usize] as i32) == (('\0' as u8) as i32))); + assert!(((empty_buf[(255) as usize] as i32) == (('\0' as u8) as i32))); + let mut prefix_buf: [u8; 32] = + *b"%\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + assert!(((prefix_buf[(0) as usize] as i32) == (('%' as u8) as i32))); + assert!(((prefix_buf[(1) as usize] as i32) == (('\0' as u8) as i32))); + assert!(((prefix_buf[(31) as usize] as i32) == (('\0' as u8) as i32))); + let mut short_buf: [u8; 16] = *b"hi\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + assert!(((short_buf[(0) as usize] as i32) == (('h' as u8) as i32))); + assert!(((short_buf[(1) as usize] as i32) == (('i' as u8) as i32))); + assert!(((short_buf[(2) as usize] as i32) == (('\0' as u8) as i32))); + assert!(((short_buf[(15) as usize] as i32) == (('\0' as u8) as i32))); + let mut exact_buf: [u8; 6] = *b"hello\0"; + assert!(((exact_buf[(0) as usize] as i32) == (('h' as u8) as i32))); + assert!(((exact_buf[(4) as usize] as i32) == (('o' as u8) as i32))); + assert!(((exact_buf[(5) as usize] as i32) == (('\0' as u8) as i32))); + assert!(((::std::mem::size_of::<[u8; 6]>() as u64) == (6_u64))); + assert!((((::std::mem::size_of::<[u8; 6]>() as u64 as u64).wrapping_sub(1_u64)) == (5_u64))); + assert!(((::std::mem::size_of::<[u8; 1]>() as u64) == (1_u64))); + assert!((((::std::mem::size_of::<[u8; 16]>() as u64 as u64).wrapping_sub(1_u64)) == (15_u64))); + return 0; +} diff --git a/tests/unit/out/unsafe/string_literals_sized_c.rs b/tests/unit/out/unsafe/string_literals_sized_c.rs new file mode 100644 index 00000000..d02baca0 --- /dev/null +++ b/tests/unit/out/unsafe/string_literals_sized_c.rs @@ -0,0 +1,37 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + let mut empty_buf: [u8; 256] = [0u8; 256]; + assert!(((empty_buf[(0) as usize] as i32) == ('\0' as i32))); + assert!(((empty_buf[(255) as usize] as i32) == ('\0' as i32))); + let mut prefix_buf: [u8; 32] = + *b"%\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + assert!(((prefix_buf[(0) as usize] as i32) == ('%' as i32))); + assert!(((prefix_buf[(1) as usize] as i32) == ('\0' as i32))); + assert!(((prefix_buf[(31) as usize] as i32) == ('\0' as i32))); + let mut short_buf: [u8; 16] = *b"hi\0\0\0\0\0\0\0\0\0\0\0\0\0\0"; + assert!(((short_buf[(0) as usize] as i32) == ('h' as i32))); + assert!(((short_buf[(1) as usize] as i32) == ('i' as i32))); + assert!(((short_buf[(2) as usize] as i32) == ('\0' as i32))); + assert!(((short_buf[(15) as usize] as i32) == ('\0' as i32))); + let mut exact_buf: [u8; 6] = *b"hello\0"; + assert!(((exact_buf[(0) as usize] as i32) == ('h' as i32))); + assert!(((exact_buf[(4) as usize] as i32) == ('o' as i32))); + assert!(((exact_buf[(5) as usize] as i32) == ('\0' as i32))); + assert!(((::std::mem::size_of::<[u8; 6]>() as u64) == (6_u64))); + assert!((((::std::mem::size_of::<[u8; 6]>() as u64 as u64).wrapping_sub(1_u64)) == (5_u64))); + assert!(((::std::mem::size_of::<[u8; 1]>() as u64) == (1_u64))); + assert!((((::std::mem::size_of::<[u8; 16]>() as u64 as u64).wrapping_sub(1_u64)) == (15_u64))); + return 0; +} diff --git a/tests/unit/out/unsafe/union_tagged_many_arms.rs b/tests/unit/out/unsafe/union_tagged_many_arms.rs index 1f9f7972..8429c230 100644 --- a/tests/unit/out/unsafe/union_tagged_many_arms.rs +++ b/tests/unit/out/unsafe/union_tagged_many_arms.rs @@ -51,7 +51,7 @@ unsafe fn main_0() -> i32 { assert!(((b.payload.unsigned_n) == (3735928559_u64))); let mut c: Slot = ::default(); c.tag = (Tag::T_TEXT as Tag); - c.payload.text = b"hello\0".as_ptr(); + c.payload.text = b"hello\0".as_ptr().cast_mut().cast_const(); assert!((((*c.payload.text.offset((0) as isize)) as i32) == ('h' as i32))); let mut d: Slot = ::default(); d.tag = (Tag::T_FLOAT as Tag); diff --git a/tests/unit/out/unsafe/union_tagged_struct_arms.rs b/tests/unit/out/unsafe/union_tagged_struct_arms.rs new file mode 100644 index 00000000..32c74dd6 --- /dev/null +++ b/tests/unit/out/unsafe/union_tagged_struct_arms.rs @@ -0,0 +1,100 @@ +extern crate libc; +use libc::*; +extern crate libcc2rs; +use libcc2rs::*; +use std::collections::BTreeMap; +use std::io::{Read, Seek, Write}; +use std::os::fd::{AsFd, FromRawFd, IntoRawFd}; +use std::rc::Rc; +#[derive(Clone, Copy, PartialEq, Debug, Default)] +enum Choice { + #[default] + C_LIST = 1, + C_LETTERS = 2, + C_INTEGERS = 3, +} +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct Branch_anon_0_anon_0 { + pub items: *mut *mut u8, + pub count: i64, + pub cursor: i64, +} +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct Branch_anon_0_anon_1 { + pub lo: i32, + pub hi: i32, + pub curr: i32, + pub step: u8, +} +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct Branch_anon_0_anon_2 { + pub lo: i64, + pub hi: i64, + pub curr: i64, + pub step: i64, + pub width: i32, +} +#[repr(C)] +#[derive(Copy, Clone)] +pub union Branch_anon_0 { + pub list: Branch_anon_0_anon_0, + pub letters: Branch_anon_0_anon_1, + pub integers: Branch_anon_0_anon_2, +} +impl Default for Branch_anon_0 { + fn default() -> Self { + unsafe { std::mem::zeroed() } + } +} +#[repr(C)] +#[derive(Copy, Clone, Default)] +pub struct Branch { + pub choice: Choice, + pub index: i32, + pub v: Branch_anon_0, +} +pub fn main() { + unsafe { + std::process::exit(main_0() as i32); + } +} +unsafe fn main_0() -> i32 { + static mut items: [*mut u8; 3] = [ + b"a\0".as_ptr().cast_mut(), + b"b\0".as_ptr().cast_mut(), + b"c\0".as_ptr().cast_mut(), + ];; + let mut p_list: Branch = ::default(); + p_list.choice = (Choice::C_LIST as Choice); + p_list.index = 0; + p_list.v.list.items = items.as_mut_ptr(); + p_list.v.list.count = 3_i64; + p_list.v.list.cursor = 1_i64; + assert!(((p_list.v.list.count) == (3_i64))); + assert!( + (((*(*p_list.v.list.items.offset((1) as isize)).offset((0) as isize)) as i32) + == ('b' as i32)) + ); + let mut p_letters: Branch = ::default(); + p_letters.choice = (Choice::C_LETTERS as Choice); + p_letters.index = 1; + p_letters.v.letters.lo = ('a' as i32); + p_letters.v.letters.hi = ('z' as i32); + p_letters.v.letters.curr = ('m' as i32); + p_letters.v.letters.step = 1_u8; + assert!((((p_letters.v.letters.hi) - (p_letters.v.letters.lo)) == (25))); + let mut p_integers: Branch = ::default(); + p_integers.choice = (Choice::C_INTEGERS as Choice); + p_integers.index = 2; + p_integers.v.integers.lo = 1_i64; + p_integers.v.integers.hi = 100_i64; + p_integers.v.integers.curr = 1_i64; + p_integers.v.integers.step = 1_i64; + p_integers.v.integers.width = 3; + assert!(((p_integers.v.integers.hi) == (100_i64))); + assert!(((p_integers.v.integers.width) == (3))); + return 0; +} diff --git a/tests/unit/out/unsafe/unique_ptr_const_deref.rs b/tests/unit/out/unsafe/unique_ptr_const_deref.rs index b7a96774..edf42cc6 100644 --- a/tests/unit/out/unsafe/unique_ptr_const_deref.rs +++ b/tests/unit/out/unsafe/unique_ptr_const_deref.rs @@ -30,12 +30,12 @@ unsafe fn main_0() -> i32 { let mut h: Holder = ::default(); h.val = Some(Box::new(10)); (unsafe { - let _h: *const Holder = (&mut h as *mut Holder); + let _h: *const Holder = (&mut h as *mut Holder).cast_const(); let _v: i32 = 42; write_val_1(_h, _v) }); return (unsafe { - let _h: *const Holder = (&mut h as *mut Holder); + let _h: *const Holder = (&mut h as *mut Holder).cast_const(); read_val_0(_h) }); } diff --git a/tests/unit/out/unsafe/va_arg_conditional.rs b/tests/unit/out/unsafe/va_arg_conditional.rs index 1bd74b04..ec9e9e47 100644 --- a/tests/unit/out/unsafe/va_arg_conditional.rs +++ b/tests/unit/out/unsafe/va_arg_conditional.rs @@ -24,14 +24,14 @@ unsafe fn main_0() -> i32 { assert!( ((unsafe { let _verbose: i32 = 1; - let _fmt: *const u8 = b"%d\0".as_ptr(); + let _fmt: *const u8 = b"%d\0".as_ptr().cast_mut().cast_const(); conditional_log_0(_verbose, _fmt, &[42.into()]) }) == (42)) ); assert!( ((unsafe { let _verbose: i32 = 0; - let _fmt: *const u8 = b"%d\0".as_ptr(); + let _fmt: *const u8 = b"%d\0".as_ptr().cast_mut().cast_const(); conditional_log_0(_verbose, _fmt, &[99.into()]) }) == (-1_i32)) ); diff --git a/tests/unit/out/unsafe/va_arg_printf.rs b/tests/unit/out/unsafe/va_arg_printf.rs index 960704cb..364d44de 100644 --- a/tests/unit/out/unsafe/va_arg_printf.rs +++ b/tests/unit/out/unsafe/va_arg_printf.rs @@ -27,13 +27,13 @@ pub fn main() { unsafe fn main_0() -> i32 { assert!( ((unsafe { - let _fmt: *const u8 = b"hello %d %d\0".as_ptr(); + let _fmt: *const u8 = b"hello %d %d\0".as_ptr().cast_mut().cast_const(); logf_1(_fmt, &[10.into(), 32.into()]) }) == (42)) ); assert!( ((unsafe { - let _fmt: *const u8 = b"x %d %d\0".as_ptr(); + let _fmt: *const u8 = b"x %d %d\0".as_ptr().cast_mut().cast_const(); logf_1(_fmt, &[1.into(), 2.into()]) }) == (3)) ); diff --git a/tests/unit/out/unsafe/va_arg_snprintf.rs b/tests/unit/out/unsafe/va_arg_snprintf.rs index 889a1659..841d65b7 100644 --- a/tests/unit/out/unsafe/va_arg_snprintf.rs +++ b/tests/unit/out/unsafe/va_arg_snprintf.rs @@ -29,7 +29,7 @@ unsafe fn main_0() -> i32 { ((unsafe { let _buf: *mut u8 = buf.as_mut_ptr(); let _size: i32 = 1; - let _fmt: *const u8 = b"%d\0".as_ptr(); + let _fmt: *const u8 = b"%d\0".as_ptr().cast_mut().cast_const(); extract_first_0(_buf, _size, _fmt, &[42.into()]) }) == (42)) ); @@ -38,7 +38,7 @@ unsafe fn main_0() -> i32 { ((unsafe { let _buf: *mut u8 = buf.as_mut_ptr(); let _size: i32 = 1; - let _fmt: *const u8 = b"%d\0".as_ptr(); + let _fmt: *const u8 = b"%d\0".as_ptr().cast_mut().cast_const(); extract_first_0(_buf, _size, _fmt, &[65.into()]) }) == (65)) ); diff --git a/tests/unit/out/unsafe/va_arg_struct_ctx.rs b/tests/unit/out/unsafe/va_arg_struct_ctx.rs index 1b7030b1..c99b3943 100644 --- a/tests/unit/out/unsafe/va_arg_struct_ctx.rs +++ b/tests/unit/out/unsafe/va_arg_struct_ctx.rs @@ -30,14 +30,14 @@ unsafe fn main_0() -> i32 { ctx.last_error = 0; (unsafe { let _ctx: *mut context = (&mut ctx as *mut context); - let _fmt: *const u8 = b"error %d\0".as_ptr(); + let _fmt: *const u8 = b"error %d\0".as_ptr().cast_mut().cast_const(); set_error_0(_ctx, _fmt, &[42.into()]) }); assert!(((ctx.last_error) == (42))); ctx.verbose = 0; (unsafe { let _ctx: *mut context = (&mut ctx as *mut context); - let _fmt: *const u8 = b"error %d\0".as_ptr(); + let _fmt: *const u8 = b"error %d\0".as_ptr().cast_mut().cast_const(); set_error_0(_ctx, _fmt, &[99.into()]) }); assert!(((ctx.last_error) == (42))); diff --git a/tests/unit/out/unsafe/vector.rs b/tests/unit/out/unsafe/vector.rs index 11ff23c0..fb44d821 100644 --- a/tests/unit/out/unsafe/vector.rs +++ b/tests/unit/out/unsafe/vector.rs @@ -99,7 +99,7 @@ unsafe fn main_0() -> i32 { assert!((((v7[(i as u64) as usize].0).is_null()) && ((v7[(i as u64) as usize].1) == (0)))); i.prefix_inc(); } - let mut p1: *const f64 = v6.as_mut_ptr(); + let mut p1: *const f64 = v6.as_mut_ptr().cast_const(); assert!(((*p1) == (2.0E+0))); let mut p2: *mut i32 = v3.as_mut_ptr(); assert!(((*p2) == (1))); diff --git a/tests/unit/string_literals.cpp b/tests/unit/string_literals.cpp new file mode 100644 index 00000000..33baffeb --- /dev/null +++ b/tests/unit/string_literals.cpp @@ -0,0 +1,26 @@ +void foo_mut(char *str) {} +void foo_const(const char *str) {} + +int main() { + const char *immutable_strings[] = {"a", "b", "c"}; + + const char *immutable_string = "hello"; + + char mutable_string_arr[] = "papanasi"; + const char immutable_string_arr[] = "papanasi"; + + const char *immutable_empty = ""; + char mutable_empty_arr[] = ""; + const char immutable_empty_arr[] = ""; + + foo_mut(mutable_string_arr); + + foo_const("world"); + foo_const(immutable_string); + foo_const(immutable_string_arr); + + foo_const(""); + foo_const(immutable_empty); + foo_const(immutable_empty_arr); + return 0; +} diff --git a/tests/unit/string_literals_c.c b/tests/unit/string_literals_c.c new file mode 100644 index 00000000..d72fcbbf --- /dev/null +++ b/tests/unit/string_literals_c.c @@ -0,0 +1,35 @@ +void foo_mut(char *str) {} +void foo_const(const char *str) {} + +int main() { + char *mutable_strings[] = {"a", "b", "c"}; + const char *immutable_strings[] = {"a", "b", "c"}; + + char *mutable_string = "hello"; + const char *immutable_string = "hello"; + + char mutable_string_arr[] = "papanasi"; + const char immutable_string_arr[] = "papanasi"; + + char *mutable_empty = ""; + const char *immutable_empty = ""; + char mutable_empty_arr[] = ""; + const char immutable_empty_arr[] = ""; + + foo_mut("world"); + foo_mut(mutable_string); + foo_mut(mutable_string_arr); + + foo_const("world"); + foo_const(mutable_string); + foo_const(immutable_string); + foo_const(mutable_string_arr); + foo_const(immutable_string_arr); + + foo_const(""); + foo_const(mutable_empty); + foo_const(immutable_empty); + foo_const(mutable_empty_arr); + foo_const(immutable_empty_arr); + return 0; +} diff --git a/tests/unit/string_literals_concat.cpp b/tests/unit/string_literals_concat.cpp new file mode 100644 index 00000000..3556c3c2 --- /dev/null +++ b/tests/unit/string_literals_concat.cpp @@ -0,0 +1,27 @@ +#include + +int main() { + const char *joined = "alpha\n" + "beta\n" + "gamma\n"; + assert(joined[0] == 'a'); + assert(joined[5] == '\n'); + assert(joined[6] == 'b'); + + char arr[] = "foo" + "bar"; + assert(arr[0] == 'f'); + assert(arr[3] == 'b'); + assert(arr[5] == 'r'); + assert(arr[6] == '\0'); + + const char *split_pieces = "abc" + "def" + "ghi"; + assert(split_pieces[0] == 'a'); + assert(split_pieces[3] == 'd'); + assert(split_pieces[6] == 'g'); + assert(split_pieces[8] == 'i'); + assert(split_pieces[9] == '\0'); + return 0; +} diff --git a/tests/unit/string_literals_concat_c.c b/tests/unit/string_literals_concat_c.c new file mode 100644 index 00000000..37159db3 --- /dev/null +++ b/tests/unit/string_literals_concat_c.c @@ -0,0 +1,20 @@ +#include + +int main(void) { + char arr[] = "foo" + "bar"; + assert(arr[0] == 'f'); + assert(arr[3] == 'b'); + assert(arr[5] == 'r'); + assert(arr[6] == '\0'); + + const char *split_pieces = "abc" + "def" + "ghi"; + assert(split_pieces[0] == 'a'); + assert(split_pieces[3] == 'd'); + assert(split_pieces[6] == 'g'); + assert(split_pieces[8] == 'i'); + assert(split_pieces[9] == '\0'); + return 0; +} diff --git a/tests/unit/string_literals_return.cpp b/tests/unit/string_literals_return.cpp new file mode 100644 index 00000000..0b828317 --- /dev/null +++ b/tests/unit/string_literals_return.cpp @@ -0,0 +1,32 @@ +#include + +const char *get_greeting() { return "hello"; } +const char *get_empty() { return ""; } + +const char *get_branch(int x) { + if (x > 0) { + return "positive"; + } + return "non-positive"; +} + +int main() { + const char *a = get_greeting(); + assert(a[0] == 'h'); + assert(a[4] == 'o'); + assert(a[5] == '\0'); + + const char *b = get_empty(); + assert(b[0] == '\0'); + + const char *c = get_branch(1); + assert(c[0] == 'p'); + assert(c[7] == 'e'); + assert(c[8] == '\0'); + + const char *d = get_branch(-1); + assert(d[0] == 'n'); + assert(d[11] == 'e'); + assert(d[12] == '\0'); + return 0; +} diff --git a/tests/unit/string_literals_return_c.c b/tests/unit/string_literals_return_c.c new file mode 100644 index 00000000..42db7ba5 --- /dev/null +++ b/tests/unit/string_literals_return_c.c @@ -0,0 +1,32 @@ +#include + +const char *get_greeting(void) { return "hello"; } +const char *get_empty(void) { return ""; } + +const char *get_branch(int x) { + if (x > 0) { + return "positive"; + } + return "non-positive"; +} + +int main(void) { + const char *a = get_greeting(); + assert(a[0] == 'h'); + assert(a[4] == 'o'); + assert(a[5] == '\0'); + + const char *b = get_empty(); + assert(b[0] == '\0'); + + const char *c = get_branch(1); + assert(c[0] == 'p'); + assert(c[7] == 'e'); + assert(c[8] == '\0'); + + const char *d = get_branch(-1); + assert(d[0] == 'n'); + assert(d[11] == 'e'); + assert(d[12] == '\0'); + return 0; +} diff --git a/tests/unit/string_literals_sized.cpp b/tests/unit/string_literals_sized.cpp new file mode 100644 index 00000000..254b1661 --- /dev/null +++ b/tests/unit/string_literals_sized.cpp @@ -0,0 +1,29 @@ +#include + +int main() { + char empty_buf[256] = ""; + assert(empty_buf[0] == '\0'); + assert(empty_buf[255] == '\0'); + + char prefix_buf[32] = "%"; + assert(prefix_buf[0] == '%'); + assert(prefix_buf[1] == '\0'); + assert(prefix_buf[31] == '\0'); + + char short_buf[16] = "hi"; + assert(short_buf[0] == 'h'); + assert(short_buf[1] == 'i'); + assert(short_buf[2] == '\0'); + assert(short_buf[15] == '\0'); + + char exact_buf[6] = "hello"; + assert(exact_buf[0] == 'h'); + assert(exact_buf[4] == 'o'); + assert(exact_buf[5] == '\0'); + + assert(sizeof("hello") == 6); + assert(sizeof("hello") - 1 == 5); + assert(sizeof("") == 1); + assert(sizeof("fifteen-bytes!!") - 1 == 15); + return 0; +} diff --git a/tests/unit/string_literals_sized_c.c b/tests/unit/string_literals_sized_c.c new file mode 100644 index 00000000..e8fdaef0 --- /dev/null +++ b/tests/unit/string_literals_sized_c.c @@ -0,0 +1,29 @@ +#include + +int main() { + char empty_buf[256] = ""; + assert(empty_buf[0] == '\0'); + assert(empty_buf[255] == '\0'); + + char prefix_buf[32] = "%"; + assert(prefix_buf[0] == '%'); + assert(prefix_buf[1] == '\0'); + assert(prefix_buf[31] == '\0'); + + char short_buf[16] = "hi"; + assert(short_buf[0] == 'h'); + assert(short_buf[1] == 'i'); + assert(short_buf[2] == '\0'); + assert(short_buf[15] == '\0'); + + char exact_buf[6] = "hello"; + assert(exact_buf[0] == 'h'); + assert(exact_buf[4] == 'o'); + assert(exact_buf[5] == '\0'); + + assert(sizeof("hello") == 6); + assert(sizeof("hello") - 1 == 5); + assert(sizeof("") == 1); + assert(sizeof("fifteen-bytes!!") - 1 == 15); + return 0; +} diff --git a/tests/unit/union_tagged_struct_arms.c b/tests/unit/union_tagged_struct_arms.c index 3cd71f8a..f5b90e18 100644 --- a/tests/unit/union_tagged_struct_arms.c +++ b/tests/unit/union_tagged_struct_arms.c @@ -1,4 +1,4 @@ -// no-compile +// no-compile: refcount #include #include