Commit 841a7fe4 authored by Matthias Braun's avatar Matthias Braun
Browse files

fix tarval_is_long() edge cases, improve unittest

parent 54dfb24d
......@@ -346,18 +346,25 @@ ir_tarval *new_tarval_from_bytes(unsigned char const *buf,
int tarval_is_long(ir_tarval *tv)
{
if (!mode_is_int(tv->mode) && !mode_is_reference(tv->mode))
return 0;
ir_mode *mode = get_tarval_mode(tv);
if (get_mode_arithmetic(mode) != irma_twos_complement)
return false;
if (get_mode_size_bytes(mode) <= sizeof(long))
return true;
if (get_mode_size_bits(tv->mode) > (int) (sizeof(long) << 3)) {
/* the value might be too big to fit in a long */
sc_max_from_bits(sizeof(long) << 3, 0, NULL);
if (sc_comp(sc_get_buffer(), tv->value) == ir_relation_less) {
/* really doesn't fit */
return 0;
}
/* the value might be too big to fit in a long */
size_t long_bits = sizeof(long)*8;
sc_max_from_bits(long_bits, mode_is_signed(mode), NULL);
if (sc_comp(tv->value, sc_get_buffer()) == ir_relation_greater)
return false;
if (mode_is_signed(mode)) {
char *min = ALLOCAN(char, sc_get_buffer_length());
sc_min_from_bits(long_bits, true, min);
sign_extend(min, long_bits, true);
if (sc_comp(tv->value, min) == ir_relation_less)
return false;
}
return 1;
return true;
}
long get_tarval_long(ir_tarval* tv)
......@@ -368,18 +375,15 @@ long get_tarval_long(ir_tarval* tv)
bool tarval_is_uint64(ir_tarval *tv)
{
if (!mode_is_int(tv->mode) && !mode_is_reference(tv->mode))
ir_mode *mode = get_tarval_mode(tv);
if (get_mode_arithmetic(mode) != irma_twos_complement)
return false;
if (get_mode_size_bytes(mode) <= sizeof(uint64_t))
return true;
if (get_mode_size_bits(tv->mode) > (int) (sizeof(uint64_t) << 3)) {
/* the value might be too big to fit in a long */
sc_max_from_bits(sizeof(uint64_t) << 3, 0, NULL);
if (sc_comp(sc_get_buffer(), tv->value) == ir_relation_less) {
/* really doesn't fit */
return false;
}
}
return true;
/* the value might be too big to fit in a long */
sc_max_from_bits(sizeof(uint64_t)*8, 0, NULL);
return sc_comp(tv->value, sc_get_buffer()) & ir_relation_less_equal;
}
uint64_t get_tarval_uint64(ir_tarval *tv)
......
#include <limits.h>
#include <assert.h>
#include "firm.h"
#include "error.h"
#include "irmode.h"
#include "tv.h"
int main() {
ir_init();
int main(void)
{
ir_init();
ir_tarval *one = new_tarval_from_long(1, mode_LLs);
ir_tarval *longmax = new_tarval_from_long(LONG_MAX, mode_LLs);
ir_tarval *longmaxp = tarval_add(longmax, one);
assert (!tarval_is_long(longmaxp));
ir_tarval *longmax2 = tarval_sub(longmaxp, one, mode_LLs);
assert (tarval_is_long(longmax2));
return 0;
ir_tarval *ulongmax
= sizeof(long) == 8 ? get_mode_max(mode_Lu)
: sizeof(long) == 4 ? get_mode_max(mode_Iu)
: (panic("unexpected long size"), NULL);
assert(tarval_is_long(ulongmax));
ir_tarval *ulongmax_s = tarval_convert_to(ulongmax, mode_Ls);
assert(tarval_is_long(ulongmax_s));
ir_tarval *ulongmax_se = tarval_convert_to(ulongmax_s, mode_LLs);
assert(tarval_is_long(ulongmax_se));
ir_tarval *ulongmax_z = tarval_convert_to(ulongmax_s, mode_LLu);
assert(!tarval_is_long(ulongmax_z));
ir_tarval *longmax = new_tarval_from_long(LONG_MAX, mode_LLs);
ir_tarval *longmin = new_tarval_from_long(LONG_MIN, mode_LLs);
assert(tarval_is_long(longmin));
assert(tarval_is_long(longmax));
ir_tarval *one = new_tarval_from_long(1, mode_LLs);
ir_tarval *longmaxp = tarval_add(longmax, one);
assert(!tarval_is_long(longmaxp));
ir_tarval *longmax3 = tarval_sub(longmaxp, one, mode_LLs);
assert(tarval_is_long(longmax3));
ir_tarval *longmax2 = sizeof(long) == 8 ? get_mode_max(mode_Ls)
: sizeof(long) == 4 ? get_mode_max(mode_Is)
: (panic("unexpected long size"), NULL);
assert(tarval_is_long(longmax2));
ir_tarval *longmin2 = sizeof(long) == 8 ? get_mode_min(mode_Ls)
: sizeof(long) == 4 ? get_mode_min(mode_Is)
: (panic("unexpected long size"), NULL);
assert(tarval_is_long(longmin2));
return 0;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment