Skip to content

Commit cea543b

Browse files
authored
Fix signed printing of integers (#511)
1 parent 3505ab4 commit cea543b

8 files changed

Lines changed: 64 additions & 8 deletions

‎cpp2rust/converter/converter.cpp‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2546,8 +2546,11 @@ bool Converter::VisitStringLiteral(clang::StringLiteral *expr) {
25462546
}
25472547
if (expr->getString().contains('\0')) {
25482548
std::string out = "(&[";
2549-
for (unsigned char c : expr->getString()) {
2550-
out += getTypedLiteral(std::to_string(c).c_str(), CharRustType()) + ", ";
2549+
for (char c : expr->getString()) {
2550+
auto value = CharRustTypeIsSigned()
2551+
? std::to_string(static_cast<signed char>(c))
2552+
: std::to_string(static_cast<unsigned char>(c));
2553+
out += getTypedLiteral(value.c_str(), CharRustType()) + ", ";
25512554
}
25522555
out += getTypedLiteral("0", CharRustType()) + "])";
25532556
StrCat(out);

‎cpp2rust/converter/converter_lib.cpp‎

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -319,15 +319,16 @@ llvm::APSInt GetIntegerLiteralValue(const clang::ASTContext &ctx,
319319
const clang::QualType *type,
320320
bool char_is_signed) {
321321
auto value = expr->getValue();
322+
auto target = type ? *type : expr->getType();
322323
bool is_signed = false;
323-
if (type && (*type)->isBuiltinType() && (*type)->isIntegerType() &&
324-
!(*type)->isBooleanType()) {
325-
value = value.zextOrTrunc(ctx.getIntWidth(*type));
324+
if (target->isBuiltinType() && target->isIntegerType() &&
325+
!target->isBooleanType()) {
326+
value = value.zextOrTrunc(ctx.getIntWidth(target));
326327
is_signed =
327-
(*type)->isSpecificBuiltinType(clang::BuiltinType::Char_S) ||
328-
(*type)->isSpecificBuiltinType(clang::BuiltinType::Char_U)
328+
target->isSpecificBuiltinType(clang::BuiltinType::Char_S) ||
329+
target->isSpecificBuiltinType(clang::BuiltinType::Char_U)
329330
? char_is_signed
330-
: (*type)->isSignedIntegerType();
331+
: target->isSignedIntegerType();
331332
}
332333
return llvm::APSInt(value, !is_signed);
333334
}

‎tests/unit/out/refcount/size_t_template_param.rs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ impl RefCtor_unsigned_long_ {
3636
}
3737
}
3838
}
39+
pub fn neg_ll_1() -> i64 {
40+
return -9000000_i64;
41+
}
42+
pub fn neg_char_2() -> i8 {
43+
return (b'\x80' as i8);
44+
}
45+
pub fn neg_int_3() -> i32 {
46+
return -1;
47+
}
3948
pub fn main() {
4049
__cpp2rust_init_globals();
4150
std::process::exit(main_0());
@@ -54,6 +63,9 @@ fn main_0() -> i32 {
5463
let mut rc: RefCtor_unsigned_long_ =
5564
RefCtor_unsigned_long_::new({ (v1.as_pointer()).reinterpret_cast::<u64>() });
5665
assert!((rc.v == 7_u64));
66+
assert!((({ neg_ll_1() }) == (-9000000_i32 as i64)));
67+
assert!(((({ neg_char_2() }) as i32) == ((b'\x80' as i8) as i32)));
68+
assert!((({ neg_int_3() }) == -1_i32));
5769
return 0;
5870
}
5971
pub fn __cpp2rust_init_globals() {}

‎tests/unit/out/refcount/string_literal_interior_null.rs‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ fn main_0() -> i32 {
2828
let mut b: i32 = ({ sum_bytes_0((*g_packet_1.with(Value::clone).borrow()).clone(), 2_u32) });
2929
assert!((a == b));
3030
assert!((a == 1));
31+
let mut high: i32 = ({ sum_bytes_0(Ptr::<i8>::from_string_literal(b"\xc2\0A"), 3_u32) });
32+
assert!((high == (194 + 65)));
3133
let mut c: i32 = ((b"\r\n.\r\n"[(0) as usize] as i32) + (b"\r\n.\r\n"[(3) as usize] as i32));
3234
assert!((c == ((('\r' as i8) as i32) + (('\r' as i8) as i32))));
3335
let mut idx: i32 = 1;

‎tests/unit/out/unsafe/size_t_template_param.rs‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@ impl RefCtor_unsigned_long_ {
3636
this
3737
}
3838
}
39+
pub unsafe fn neg_ll_1() -> i64 {
40+
return -9000000_i64;
41+
}
42+
pub unsafe fn neg_char_2() -> libc::c_char {
43+
return (b'\x80' as libc::c_char);
44+
}
45+
pub unsafe fn neg_int_3() -> i32 {
46+
return -1;
47+
}
3948
pub fn main() {
4049
unsafe {
4150
__cpp2rust_init_globals();
@@ -55,6 +64,9 @@ unsafe fn main_0() -> i32 {
5564
let mut rc: RefCtor_unsigned_long_ =
5665
RefCtor_unsigned_long_::new({ &*(&raw const v1).cast::<u64>() });
5766
assert!(((rc.v) == (7_u64)));
67+
assert!(((unsafe { neg_ll_1() }) == (-9000000_i32 as i64)));
68+
assert!((((unsafe { neg_char_2() }) as i32) == ((b'\x80' as libc::c_char) as i32)));
69+
assert!(((unsafe { neg_int_3() }) == (-1_i32)));
5870
return 0;
5971
}
6072
pub unsafe fn __cpp2rust_init_globals() {}

‎tests/unit/out/unsafe/string_literal_interior_null.rs‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,19 @@ unsafe fn main_0() -> i32 {
5050
});
5151
assert!(((a) == (b)));
5252
assert!(((a) == (1)));
53+
let mut high: i32 = (unsafe {
54+
sum_bytes_0(
55+
(&[
56+
(-62 as libc::c_char),
57+
(0 as libc::c_char),
58+
(65 as libc::c_char),
59+
(0 as libc::c_char),
60+
])
61+
.as_ptr(),
62+
3_u32,
63+
)
64+
});
65+
assert!(((high) == ((194) + (65))));
5366
let mut c: i32 = (((*c"\r\n.\r\n".as_ptr().offset((0) as isize)) as i32)
5467
+ ((*c"\r\n.\r\n".as_ptr().offset((3) as isize)) as i32));
5568
assert!(((c) == ((('\r' as libc::c_char) as i32) + (('\r' as libc::c_char) as i32))));

‎tests/unit/size_t_template_param.cpp‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,12 @@ template <class T> struct RefCtor {
1616
RefCtor(const T &x) : v(x + 1) {}
1717
};
1818

19+
template <long long N> static long long neg_ll() { return N; }
20+
21+
template <char C> static char neg_char() { return C; }
22+
23+
template <int N> static int neg_int() { return N; }
24+
1925
int main() {
2026
size_t a1[] = {1, 2, 3};
2127
assert(array_ref(a1) == 3);
@@ -28,5 +34,9 @@ int main() {
2834
size_t v1 = 6;
2935
RefCtor<size_t> rc(v1);
3036
assert(rc.v == 7);
37+
38+
assert(neg_ll<-9000000>() == -9000000);
39+
assert(neg_char<'\x80'>() == '\x80');
40+
assert(neg_int<-1>() == -1);
3141
return 0;
3242
}

‎tests/unit/string_literal_interior_null.cpp‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ int main() {
1818
assert(a == b);
1919
assert(a == 1);
2020

21+
int high = sum_bytes("\xc2\x00\x41", 3);
22+
assert(high == 0xc2 + 0x41);
23+
2124
int c = "\r\n.\r\n"[0] + "\r\n.\r\n"[3];
2225
assert(c == '\r' + '\r');
2326

0 commit comments

Comments
 (0)