Fix shortening casts of long long

see added testcase.
This commit is contained in:
Michael Matz 2018-03-31 21:52:20 +02:00
parent c41caac02d
commit f0a25ca263
2 changed files with 12 additions and 3 deletions

View File

@ -2633,18 +2633,22 @@ static void gen_cast(CType *type)
tcc_warning("nonportable conversion from pointer to char/short");
}
force_charshort_cast(dbt);
#if PTR_SIZE == 4
} else if ((dbt & VT_BTYPE) == VT_INT) {
/* scalar to int */
if ((sbt & VT_BTYPE) == VT_LLONG) {
#if PTR_SIZE == 4
/* from long long: just take low order word */
lexpand();
vpop();
}
#else
vpushi(0xffffffff);
vtop->type.t |= VT_UNSIGNED;
gen_op('&');
#endif
}
/* if lvalue and single word type, nothing to do because
the lvalue already contains the real type size (see
VT_LVAL_xxx constants) */
#endif
}
}
} else if ((dbt & VT_BTYPE) == VT_PTR && !(vtop->r & VT_LVAL)) {

View File

@ -2491,6 +2491,11 @@ void longlong_test(void)
a = 0x123;
long long *p = &a;
llshift(*p, 5);
/* shortening followed by widening */
unsigned long long u = 0x8000000000000001ULL;
u = (unsigned)(u + 1);
printf("long long u=" ULONG_LONG_FORMAT "\n", u);
}
void manyarg_test(void)