From a66828caff16a4ad64b9d69b5db1c5a5e60418cc Mon Sep 17 00:00:00 2001 From: Jay Berkenbilt Date: Wed, 19 Jun 2019 18:53:22 -0400 Subject: New safe type converters in QIntC --- libtests/build.mk | 1 + libtests/qintc.cc | 57 ++++++++++++++++++++++++++++++++++++++++++ libtests/qtest/qintc.test | 18 +++++++++++++ libtests/qtest/qintc/qintc.out | 13 ++++++++++ 4 files changed, 89 insertions(+) create mode 100644 libtests/qintc.cc create mode 100644 libtests/qtest/qintc.test create mode 100644 libtests/qtest/qintc/qintc.out (limited to 'libtests') diff --git a/libtests/build.mk b/libtests/build.mk index 5c1ee56a..4313b630 100644 --- a/libtests/build.mk +++ b/libtests/build.mk @@ -17,6 +17,7 @@ BINS_libtests = \ numrange \ pointer_holder \ predictors \ + qintc \ qutil \ random \ rc4 \ diff --git a/libtests/qintc.cc b/libtests/qintc.cc new file mode 100644 index 00000000..79fc6f53 --- /dev/null +++ b/libtests/qintc.cc @@ -0,0 +1,57 @@ +#include +#include +#include + +#define try_convert(exp_pass, fn, i) \ + try_convert_real(#fn "(" #i ")", exp_pass, fn, i) + +template +static void try_convert_real( + char const* description, bool exp_pass, + To (*fn)(From const&), From const& i) +{ + bool passed = false; + try + { + To result = fn(i); + passed = true; + std::cout << description << ": " << i << " " << result; + } + catch (std::range_error& e) + { + std::cout << description << ": " << e.what(); + passed = false; + } + std::cout << ((passed == exp_pass) ? " PASSED" : " FAILED") << std::endl; +} + +int main() +{ + uint32_t u1 = 3141592653U; // Too big for signed type + int32_t i1 = -1153374643; // Same bit pattern as u1 + uint64_t ul1 = 1099511627776LL; // Too big for 32-bit + uint64_t ul2 = 12345; // Fits into 32-bit + int32_t i2 = 81; // Fits in char and uchar + char c1 = '\xf7'; // Signed vaule when char + + // Verify i1 and u1 have same bit pattern + assert(static_cast(i1) == u1); + // Verify that we can unsafely convert between char and unsigned char + assert(c1 == static_cast(static_cast(c1))); + + try_convert(true, QIntC::to_int, i1); + try_convert(true, QIntC::to_uint, u1); + try_convert(false, QIntC::to_int, u1); + try_convert(false, QIntC::to_uint, i1); + try_convert(false, QIntC::to_int, ul1); + try_convert(true, QIntC::to_int, ul2); + try_convert(true, QIntC::to_uint, ul2); + try_convert(true, QIntC::to_offset, u1); + try_convert(true, QIntC::to_offset, i1); + try_convert(false, QIntC::to_size, i1); + try_convert(true, QIntC::to_char, i2); + try_convert(true, QIntC::to_uchar, i2); + try_convert(false, QIntC::to_uchar, c1); + + return 0; +} diff --git a/libtests/qtest/qintc.test b/libtests/qtest/qintc.test new file mode 100644 index 00000000..4b2dc3a5 --- /dev/null +++ b/libtests/qtest/qintc.test @@ -0,0 +1,18 @@ +#!/usr/bin/env perl +require 5.008; +BEGIN { $^W = 1; } +use strict; + +chdir("qintc") or die "chdir testdir failed: $!\n"; + +require TestDriver; + +my $td = new TestDriver('qintc'); + +$td->runtest("QINTC", + {$td->COMMAND => "qintc"}, + {$td->FILE => "qintc.out", + $td->EXIT_STATUS => 0}, + $td->NORMALIZE_NEWLINES | $td->RM_WS_ONLY_LINES); + +$td->report(1); diff --git a/libtests/qtest/qintc/qintc.out b/libtests/qtest/qintc/qintc.out new file mode 100644 index 00000000..9b6d35d9 --- /dev/null +++ b/libtests/qtest/qintc/qintc.out @@ -0,0 +1,13 @@ +QIntC::to_int(i1): -1153374643 -1153374643 PASSED +QIntC::to_uint(u1): 3141592653 3141592653 PASSED +QIntC::to_int(u1): integer out of range converting 3141592653 from a 4-byte unsigned type to a 4-byte signed type PASSED +QIntC::to_uint(i1): integer out of range converting -1153374643 from a 4-byte signed type to a 4-byte unsigned type PASSED +QIntC::to_int(ul1): integer out of range converting 1099511627776 from a 8-byte unsigned type to a 4-byte signed type PASSED +QIntC::to_int(ul2): 12345 12345 PASSED +QIntC::to_uint(ul2): 12345 12345 PASSED +QIntC::to_offset(u1): 3141592653 3141592653 PASSED +QIntC::to_offset(i1): -1153374643 -1153374643 PASSED +QIntC::to_size(i1): integer out of range converting -1153374643 from a 4-byte signed type to a 8-byte unsigned type PASSED +QIntC::to_char(i2): 81 Q PASSED +QIntC::to_uchar(i2): 81 Q PASSED +QIntC::to_uchar(c1): integer out of range converting ÷ from a 1-byte signed type to a 1-byte unsigned type PASSED -- cgit v1.2.3-54-g00ecf