Alien-TinyCCx
view release on metacpan or search on metacpan
src/tests/tcctest.c view on Meta::CPAN
int global_data_getstuff (int *p, int i)
{
return *p + i;
}
void global_data_test (void)
{
global_data.a[0] = 42;
global_data.b[0] = &global_data.a[0];
global_data_callit (0);
printf ("%d\n", global_data.a[0]);
}
struct cmpcmpS
{
unsigned char fill : 3;
unsigned char b1 : 1;
unsigned char b2 : 1;
unsigned char fill2 : 3;
};
int glob1, glob2, glob3;
void compare_comparisons (struct cmpcmpS *s)
{
if (s->b1 != (glob1 == glob2)
|| (s->b2 != (glob1 == glob3)))
printf ("comparing comparisons broken\n");
}
void cmp_comparison_test(void)
{
struct cmpcmpS s;
s.b1 = 1;
glob1 = 42; glob2 = 42;
s.b2 = 0;
glob3 = 43;
compare_comparisons (&s);
}
int fcompare (double a, double b, int code)
{
switch (code) {
case 0: return a == b;
case 1: return a != b;
case 2: return a < b;
case 3: return a >= b;
case 4: return a > b;
case 5: return a <= b;
}
}
void math_cmp_test(void)
{
double nan = 0.0/0.0;
double one = 1.0;
double two = 2.0;
int comp = 0;
#define bug(a,b,op,iop,part) printf("Test broken: %s %s %s %s %d\n", #a, #b, #op, #iop, part)
/* This asserts that "a op b" is _not_ true, but "a iop b" is true.
And it does this in various ways so that all code generation paths
are checked (generating inverted tests, or non-inverted tests, or
producing a 0/1 value without jumps (that's done in the fcompare
function). */
#define FCMP(a,b,op,iop,code) \
if (fcompare (a,b,code)) \
bug (a,b,op,iop,1); \
if (a op b) \
bug (a,b,op,iop,2); \
if (a iop b) \
; \
else \
bug (a,b,op,iop,3); \
if ((a op b) || comp) \
bug (a,b,op,iop,4); \
if ((a iop b) || comp) \
; \
else \
bug (a,b,op,iop,5);
/* Equality tests. */
FCMP(nan, nan, ==, !=, 0);
FCMP(one, two, ==, !=, 0);
FCMP(one, one, !=, ==, 1);
/* Non-equality is a bit special. */
if (!fcompare (nan, nan, 1))
bug (nan, nan, !=, ==, 6);
/* Relational tests on numbers. */
FCMP(two, one, <, >=, 2);
FCMP(one, two, >=, <, 3);
FCMP(one, two, >, <=, 4);
FCMP(two, one, <=, >, 5);
/* Relational tests on NaNs. Note that the inverse op here is
always !=, there's no operator in C that is equivalent to !(a < b),
when NaNs are involved, same for the other relational ops. */
FCMP(nan, nan, <, !=, 2);
FCMP(nan, nan, >=, !=, 3);
FCMP(nan, nan, >, !=, 4);
FCMP(nan, nan, <=, !=, 5);
}
double get100 () { return 100.0; }
void callsave_test(void)
{
#if defined __i386__ || defined __x86_64__ || defined __arm__
int i, s; double *d; double t;
s = sizeof (double);
printf ("callsavetest: %d\n", s);
d = alloca (sizeof(double));
d[0] = 10.0;
/* x86-64 had a bug were the next call to get100 would evict
the lvalue &d[0] as VT_LLOCAL, and the reload would be done
in int type, not pointer type. When alloca returns a pointer
with the high 32 bit set (which is likely on x86-64) the access
generates a segfault. */
i = d[0] > get100 ();
printf ("%d\n", i);
( run in 0.640 second using v1.01-cache-2.11-cpan-e1769b4cff6 )