/* addCast - adds casts to a type specified by RESULT_TYPE */
/*-----------------------------------------------------------------*/
static ast *
-addCast (ast *tree, RESULT_TYPE resultType, bool upcast)
+addCast (ast *tree, RESULT_TYPE resultType, bool promote)
{
sym_link *newLink;
bool upCasted = FALSE;
switch (resultType)
{
case RESULT_TYPE_NONE:
- /* char: promote to int */
- if (!upcast ||
+ /* if thing smaller than int must be promoted to int */
+ if (!promote ||
getSize (tree->etype) >= INTSIZE)
+ /* promotion not necessary or already an int */
+ return tree;
+ /* char and bits: promote to int */
+ newLink = newIntLink();
+ upCasted = TRUE;
+ break;
+ case RESULT_TYPE_BIT:
+ if (!promote ||
+ /* already an int */
+ bitsForType (tree->etype) >= 16 ||
+ /* bit to bit operation: don't promote, the code generators
+ hopefully know everything about promotion rules */
+ bitsForType (tree->etype) == 1)
return tree;
newLink = newIntLink();
upCasted = TRUE;
}
#endif
/* char: promote to int */
- if (!upcast ||
+ if (!promote ||
getSize (tree->etype) >= INTSIZE)
return tree;
newLink = newIntLink();
upCasted = TRUE;
break;
case RESULT_TYPE_OTHER:
- if (!upcast)
+ if (!promote)
return tree;
/* return type is long, float: promote char to int */
if (getSize (tree->etype) >= INTSIZE)
TETYPE (tree) = TTYPE (tree) = tree->opval.val->type;
return addCast (tree, resultType, TRUE);
}
- tree->left = addCast (tree->left, resultType, TRUE);
+
+ if (resultType == RESULT_TYPE_BIT &&
+ IS_UNSIGNED (tree->left->etype) &&
+ getSize (tree->left->etype) < INTSIZE)
+ {
+ /* promotion rules are responsible for this strange result:
+ bit -> int -> ~int -> bit
+ uchar -> int -> ~int -> bit
+ */
+ werror(W_COMPLEMENT);
+
+ /* optimize bit-result, even if we optimize a buggy source */
+ tree->type = EX_VALUE;
+ tree->opval.val = constVal ("1");
+ }
+ else
+ tree->left = addCast (tree->left, resultType, TRUE);
LRVAL (tree) = 1;
COPYTYPE (TTYPE (tree), TETYPE (tree), LTYPE (tree));
return tree;
ast *
optimizeGetWord (ast * tree, RESULT_TYPE resultType)
{
- unsigned int i;
+ unsigned int i = 0;
ast * expr;
ast * count = NULL;