File: test_int64_test.c

package info (click to toggle)
dwarfutils 1%3A0.11.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 11,732 kB
  • sloc: ansic: 119,558; cpp: 6,689; xml: 4,736; sh: 1,674; python: 1,117; makefile: 1,099
file content (184 lines) | stat: -rw-r--r-- 5,182 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/* Thanks to David Grason
   gist.github.com/DavidEGrayson/06cf7ea73f82a05490ba

   Any errors here were added by me in my modifications.
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <limits.h>
#include <limits.h>

int failcount = 0;

#undef LLONG_MAX
#undef LLONG_MIN
#undef INT64_MAX
#undef INT64_MIN
#ifndef LLONG_MAX
#define LLONG_MAX    9223372036854775807LL
#endif
#ifndef LLONG_MIN
#define LLONG_MIN    (-LLONG_MAX - 1LL)
#endif
#ifndef ULLONG_MAX
#define ULLONG_MAX   18446744073709551615ULL
#endif
#define INT64_MAX LLONG_MAX
#define INT64_MIN LLONG_MIN

/*  In libdwarf, Dwarf_Signed is a 64bit integer.
    No lesser size (or greater size) is supported
    at this time.
*/

/*  Multiplies two 64-bit signed ints if possible.
    Returns 0 on success, and puts the product of x and y
    into the result.
    Returns 1 if there was an overflow. */
static
int
int64_mult(long long x, long long y, long long * result)
{
    *result = 0;
    if (x > 0 && y > 0 && x > INT64_MAX / y) return 1;
    if (x < 0 && y > 0 && x < INT64_MIN / y) return 1;
    if (x > 0 && y < 0 && y < INT64_MIN / x) return 1;
    if (x < 0 && y < 0 &&
        (x <= INT64_MIN || y <= INT64_MIN || -x > INT64_MAX / -y))
        return 1;
    *result = x * y;
    return 0;
}

static
void test_int64_mult_success(long long x, long long y,
    long long expected,int line)
{
    long long result;

    /* x * y */
    if (int64_mult(x, y, &result))
    {
        fprintf(stderr, "unexpected overflow: %lld %lld line %d\n",
            x, y,line);
        ++failcount;
    }
    if (result != expected)
    {
        fprintf(stderr, "wrong result: %lld %lld %lld %lld line %d\n",
            x, y, expected, result,line);
        ++failcount;
    }

    // y * x should be the same
    if (int64_mult(y, x, &result))
    {
        fprintf(stderr, "unexpected overflow: %lld %lld line %d\n",
            y, x,line);
        ++failcount;
    }
    if (result != expected)
    {
        fprintf(stderr, "wrong result: %lld %lld %lld %lld line %d\n",
            y, x, expected, result,line);
        ++failcount;
    }
}

static
void test_int64_mult_error(long long x, long long y, int line)
{
    long long result;

    /* x * y */
    if (int64_mult(x, y, &result) == 0)
    {
        fprintf(stderr, "unexpected success: %lld %lld line %d\n",
            x, y,line);
        ++failcount;
    }

    /* y * x should be the same */
    if (int64_mult(y, x, &result) == 0)
    {
        fprintf(stderr, "unexpected success: %lld %lld line %d\n",
            y, x,line);
        ++failcount;
    }
}

int main(void)
{
    /* min, min */
    test_int64_mult_error(INT64_MIN, INT64_MIN,__LINE__);

    /* min, min/100 */
    test_int64_mult_error(INT64_MIN, INT64_MIN / 100,__LINE__);

    /* min, 0 */
    test_int64_mult_error(INT64_MIN, -2,__LINE__);
    test_int64_mult_error(INT64_MIN, -1,__LINE__);
    test_int64_mult_success(INT64_MIN, 0, 0,__LINE__);
    test_int64_mult_success(INT64_MIN, 1, INT64_MIN,__LINE__);
    test_int64_mult_error(INT64_MIN, 2,__LINE__);

    /* min, max/100 */
    test_int64_mult_error(INT64_MIN, INT64_MAX / 100,__LINE__);

    /* min, max */
    test_int64_mult_error(INT64_MIN, INT64_MAX,__LINE__);

    /* min/100, min/100 */
    test_int64_mult_error(INT64_MIN / 100, INT64_MIN / 100,__LINE__);

    /* min/100, 0 */
    test_int64_mult_error(INT64_MIN / 100, -101,__LINE__);
    test_int64_mult_success(INT64_MIN / 100, -100,
        0x7ffffffffffffff8,__LINE__);
    test_int64_mult_success(INT64_MIN / 100, -99,
        0x7eb851eb851eb84a,__LINE__);
    test_int64_mult_success(INT64_MIN / 100, 0, 0,__LINE__);
    test_int64_mult_success(INT64_MIN / 100, 100,
        -0x7ffffffffffffff8,__LINE__);
    test_int64_mult_error(INT64_MIN / 100, 101,__LINE__);

    /* min/100, max/100 */
    test_int64_mult_error(INT64_MIN / 100, INT64_MAX / 100,__LINE__);

    /* min/100, max */
    test_int64_mult_error(INT64_MIN / 100, INT64_MAX,__LINE__);

    /* 0, 0 */
    test_int64_mult_success(0, 0, 0,__LINE__);
    test_int64_mult_success(0, 1, 0,__LINE__);
    test_int64_mult_success(1, 1, 1,__LINE__);
    test_int64_mult_success(1, 3, 3,__LINE__);
    test_int64_mult_success(3, 3, 9,__LINE__);

    /* 0, max/100 */
    test_int64_mult_error(INT64_MAX / 100, -101,__LINE__);
    test_int64_mult_success(INT64_MAX / 100, -100,
        -0x7ffffffffffffff8,__LINE__);
    test_int64_mult_success(INT64_MAX / 100, -99,
        -0x7eb851eb851eb84a,__LINE__);
    test_int64_mult_success(INT64_MAX / 100, 0, 0,__LINE__);
    test_int64_mult_success(INT64_MAX / 100, 100,
        0x7ffffffffffffff8,__LINE__);
    test_int64_mult_error(INT64_MAX / 100, 101,__LINE__);

    /* 0, max */
    test_int64_mult_error(-2, INT64_MAX,__LINE__);
    test_int64_mult_success(-1, INT64_MAX, -INT64_MAX,__LINE__);
    test_int64_mult_success(0, INT64_MAX, 0,__LINE__);
    test_int64_mult_success(1, INT64_MAX, INT64_MAX,__LINE__);
    test_int64_mult_error(2, INT64_MAX,__LINE__);

    /* max/100, max */
    test_int64_mult_error(INT64_MAX / 100, INT64_MAX,__LINE__);
    if (failcount) {
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}