Skip to content

Commit

Permalink
more chapter 11/12 extra credit test cases
Browse files Browse the repository at this point in the history
  • Loading branch information
nlsandler committed May 24, 2024
1 parent 6e5f540 commit 21da4fb
Show file tree
Hide file tree
Showing 10 changed files with 200 additions and 10 deletions.
2 changes: 1 addition & 1 deletion expected_results.json

Large diffs are not rendered by default.

17 changes: 16 additions & 1 deletion test_properties.json
Original file line number Diff line number Diff line change
Expand Up @@ -591,6 +591,9 @@
"chapter_11/invalid_labels/extra_credit/switch_duplicate_cases_2.c": [
"switch"
],
"chapter_11/invalid_labels/extra_credit/bitshift_duplicate_cases.c": [
"switch", "bitwise"
],
"chapter_11/valid/extra_credit/bitwise_long_op.c": [
"bitwise"
],
Expand All @@ -606,13 +609,19 @@
"chapter_11/valid/extra_credit/increment_long.c": [
"increment"
],
"chapter_11/valid/extra_credit/compound_bitshift.c": [
"bitwise", "compound"
],
"chapter_11/valid/extra_credit/compound_bitwise.c": [
"bitwise", "compound"
],
"chapter_11/valid/extra_credit/switch_int.c": [
"switch"
],
"chapter_11/valid/extra_credit/switch_long.c": [
"switch"
],
"chapter_12/invalid_labels/extra_credit/switch_duplicate_case.c": [
"chapter_12/invalid_labels/extra_credit/switch_duplicate_cases.c": [
"switch"
],
"chapter_12/valid/extra_credit/bitwise_unsigned_ops.c": [
Expand All @@ -624,6 +633,12 @@
"chapter_12/valid/extra_credit/compound_assign_uint.c": [
"compound"
],
"chapter_12/valid/extra_credit/compound_bitshift.c": [
"compound", "bitwise"
],
"chapter_12/valid/extra_credit/compound_bitwise.c": [
"compound", "bitwise"
],
"chapter_12/valid/extra_credit/switch_uint.c": [
"switch"
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// Test that we correctly infer type of bitshift expression;
// x << y has type of x, not common type of x and y

int main(void) {
int x = 100;
switch (x << 2l) { // x << 2 == 400
// these cases are duplicates b/c they'll both be converted to
// the type of the switch expression - which is int, NOT long
case 34359738768l: // 2**35 + 400
return 1;
case 400:
return 0;
}
return 10;
}
14 changes: 10 additions & 4 deletions tests/chapter_11/valid/extra_credit/bitshift.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ int main(void) {
return 3;
}

// try shift count > 32 (shift count between 32 and 64 is undefined when
// shifting an int, well-defined when shifting a long)
if ((40l << 40) != 43980465111040l) {
return 4;
}

// use long as right shift operand
// NOTE: we shouldn't perform usual arithmetic conversions here
// (result has same type as left operand) but we won't be able to fully
Expand All @@ -32,21 +38,21 @@ int main(void) {

// should be -2^28
if (i >> long_shiftcount != -268435456) {
return 4;
return 5;
}

i = -1;
if (i >> 10l != -1) {
return 5;
return 6;
}

// make sure we didn't shift any bits into i's neighbors
if (i_neighbor1) {
return 6;
return 7;
}

if (i_neighbor2) {
return 7;
return 8;
}

return 0;
Expand Down
34 changes: 34 additions & 0 deletions tests/chapter_11/valid/extra_credit/compound_bitshift.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Test compound bit shift operators with mix of types

int main(void) {

// shift int using long shift count
int x = 100;
x <<= 22l;
if (x != 419430400) {
return 1; // fail
}

// try right shift; validate result of expression
if ((x >>= 4l) != 26214400) {
return 2; // fail
}

// also validate side effect of updating variable
if (x != 26214400) {
return 3;
}

// now try shifting a long with an int shift count
long l = 12345l;
if ((l <<= 33) != 106042742538240l) {
return 4;
}

l = -l;
if ((l >>= 10) != -103557365760l) {
return 5;
}

return 0; // success
}
49 changes: 49 additions & 0 deletions tests/chapter_11/valid/extra_credit/compound_bitwise.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
int main(void) {

// bitwise compound operations on long integers
long l1 = 71777214294589695l; // 0x00ff00ff00ff00ff
long l2 = -4294967296; // -2^32; upper 32 bits are 1, lower 32 bits are 0

l1 &= l2;
if (l1 != 71777214277877760l) {
return 1; // fail
}

l2 |= 100l;
if (l2 != -4294967196) {
return 2;
}

l1 ^= -9223372036854775807l;
if (l1 != -9151594822576898047l /* 0x80ff00ff00000001 */ ) {
return 3;
}

// if rval is int, convert to common type
l1 = 4611686018427387903l; // 0x3fffffffffffffff
int i = -1073741824; // 0b1100....0, or 0xc0000000
// 1. sign-extend i to 64 bits; upper 32 bits are all 1s
// 2. take bitwise AND of sign-extended value with l1
// 3. result (stored in l1) is 3fffffffc0000000;
// upper bits match l1, lower bits match i
l1 &= i;
if (l1 != 4611686017353646080l) {
return 4;
}

// if lval is int, convert to common type, perform operation, then convert back
i = -2147483648l; // 0x80000000
// check result and side effect
// 1. sign extend 0x80000000 to 0x0000000080000000
// 2. calculate 0x0000000080000000 | 0x00ff00ff00ff00ff = 0x000ff00ff80ff00ff
// 3. truncate to 0x80ff00ff on assignment
if ((i |= 71777214294589695l) != -2130771713) {
return 5;
}
if (i != -2130771713) {
return 6;
}

return 0; // success

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ int main(void) {
switch(ui) {
case 4294967295u: // 2^32 - 1
return 0;
case -1l: // this will be converted to 2^32 - 1
case 1099511627775l: // 0xffffffffff; this will be converted to 2^32 - 1
return 1;
default: return 2;
}
Expand Down
17 changes: 14 additions & 3 deletions tests/chapter_12/valid/extra_credit/bitwise_unsigned_shift.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,24 @@
/* Bit-shift operations do not perform the usual arithmetic conversions. */
/* Tests for bit-shift operations on unsigned integers */

int main(void) {

unsigned int ui = -1u; // 2^32 - 1, or 4294967295

/* shifting left by 2 is like subtracting 3.
* note that we don't cast ui to a long first
/* Shifting left by 2 is like subtracting 3;
* note that we don't cast ui to a long first.
* Also note that the result wraps around; it's
* equivalent to (ui * 2^2) % UINT_MAX.
*/
if ((ui << 2l) != 4294967292) {
return 1;
}

/* Shifting right by 2 is like dividing by 4;
* note that we need to use shr (logical shift) instruction
* rather than sar (arithmetic shift) instruction */
if ((ui >> 2) != 1073741823) {
return 2;
}

return 0; // success
}
18 changes: 18 additions & 0 deletions tests/chapter_12/valid/extra_credit/compound_bitshift.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
int main(void) {

// make sure we don't convert to common type before performing shift operation
int i = -2;
// don't convert i to common (unsigned) type; if we do, we'll use logical
// instead of arithmetic shift, leading to wrong result
i >>= 3u;
if (i != -1) {
return 1;
}

unsigned long ul = 18446744073709551615UL; // 2^64 - 1
ul <<= 44; // 0 out lower 44 bits
if (ul != 18446726481523507200ul) {
return 2; // fail
}
return 0; // success
}
42 changes: 42 additions & 0 deletions tests/chapter_12/valid/extra_credit/compound_bitwise.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
int main(void) {

unsigned long ul = 18446460386757245432ul; // 0xfffefdfcfbfaf9f8
ul &= -1000; // make sure we sign-extend -1000 to unsigned long
if (ul != 18446460386757244952ul /* 0xfffefdfcfbfaf818 */) {
return 1; // fail
}

ul |= 4294967040u; // 0xffffff00 - make sure we zero-extend this to unsigned long

if (ul != 18446460386824683288ul /* 0xfffefdfcffffff18 */) {
return 2; // fail
}

// make sure that we convert result _back_ to type of lvalue,
// and that we don't clobber nearby values (e.g. by trying to assign 8-byte)
// result to four-byte ui variable
int i = 123456;
unsigned int ui = 4042322160u; // 0xf0f0f0f0
long l = -252645136; // 0xffffffffff0f0f0f0
// 1. zero-extend ui to 8-bytes
// 2. XOR w/ l, resulting in 0xffffffff00000000
// 3. truncate back to 4 bytes, resulting in 0
// then check value of expression (i.e. value of ui)
if (ui ^= l) {
return 3; // fail
}

// check side effect (i.e. updating ui)
if (ui) {
return 4; // fail
}
// check neighbors
if (i != 123456) {
return 5;
}
if (l != -252645136) {
return 6;
}

return 0; // success
}

0 comments on commit 21da4fb

Please sign in to comment.