Skip to content

Commit

Permalink
fixed unsigned casting codegen bug; added new tests
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilippRados committed Jun 8, 2024
1 parent ca92f2a commit 8c03bb2
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 0 deletions.
25 changes: 25 additions & 0 deletions tests/fixtures/unsigned_calcs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#include <stdio.h>

long foo(unsigned);
long foo(unsigned int a) { return a; }

int main() {
printf("%ld\n", foo((unsigned short)-1));

unsigned int c = 2147483649;
int d = 2000;
int s = d + c;
printf("%d\n", c);
printf("%d\n", s);

unsigned long i = 999999u * 9999999 * 999999;
unsigned long l = -9223372036854775808u + 1;
printf("%lu\n", i);
printf("%lu\n", l);

int eq = 18446744073709551615u == 18446744073709551615ll;
printf("%d\n", eq);

unsigned char n = 372897938;
printf("%ld\n", (long)n);
}
7 changes: 7 additions & 0 deletions tests/snapshots/success_unsigned_calcs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
65535
-2147483647
-2147481647
420793087
9223372036854775809
1
146
10 changes: 10 additions & 0 deletions wrecc_compiler/src/compiler/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1023,6 +1023,16 @@ impl Compiler {
if value_reg.get_type().size() < 4 {
self.write_out(Lir::Movz(value_reg.clone(), dest_reg.clone()));
} else {
// convert registers since otherwise will read memory that isnt
// that doesnt belong to value_reg: casting unsigned int to long
// int a: -4(%rbp), 4 bytes allocate
// `movq -4(%rbp), %r10`, would read 8 bytes
value_reg = convert_reg!(
self,
value_reg,
Register::Temp(..) | Register::Stack(..) | Register::Label(..)
);

value_reg.set_type(new_type);
self.write_out(Lir::Mov(value_reg.clone(), dest_reg.clone()))
}
Expand Down
2 changes: 2 additions & 0 deletions wrecc_compiler/src/compiler/typechecker/fold.rs
Original file line number Diff line number Diff line change
Expand Up @@ -722,6 +722,7 @@ mod tests {
"(unsigned)420793087",
"unsigned int",
);
assert_fold_type("999999u * 9999999 * 999999", "420793087u", "unsigned int");
assert_fold_error!(
"999999 * 9999999 * 999999",
ErrorKind::IntegerOverflow(QualType {
Expand Down Expand Up @@ -787,5 +788,6 @@ mod tests {
assert_fold("(short *)1 + -5", "(short*)-9");
assert_fold("(int*)1 + -9223372036854775807", "(int*)5");
assert_fold_error!("(int*)1 + -9223372036854775808", ErrorKind::ScaleOverflow);
assert_fold_error!("(int*)1 - 9223372036854775809ul", ErrorKind::ScaleOverflow);
}
}
2 changes: 2 additions & 0 deletions wrecc_compiler/src/compiler/typechecker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2614,6 +2614,8 @@ mod tests {
assert_type!("(void*)1 == a", "int", "long* a;");
assert_type!("0 == a", "int", "long* a;");
assert_type!("a == 0", "int", "int* a;");
assert_type!("a == 2l", "int", "unsigned int a;");
assert_type!("a == 2lu", "int", "int a;");

assert_type_err!("1 == a", ErrorKind::InvalidComp(..), "long *a;");
assert_type_err!("a == b", ErrorKind::InvalidComp(..), "int *a; long *b;");
Expand Down

0 comments on commit 8c03bb2

Please sign in to comment.