From: bernhardheld Date: Thu, 1 Jan 2004 21:59:26 +0000 (+0000) Subject: Many signedness and type propagation fixes X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=808f5e7fbf3de6ae5c1effcdf2764fb6d706b1cf;p=fw%2Fsdcc Many signedness and type propagation fixes git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3072 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/.version b/.version index e75da3e6..00355e29 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.3.6 +2.3.7 diff --git a/ChangeLog b/ChangeLog index ef4db4fb..c6d252c5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,32 @@ +2004-01-01 Bernhard Held + + Many signedness and type propagation fixes: + * src/SDCCicode.c: made geniCodeCast() static + replaced SPEC_ by IS_ (cosmetic) + (operandOperation): fixed div and mod operation + (usualBinaryConversions): added support for promotion of char + (geniCodeMultiply): replaced (unsigned long) by (TYPE_UDWORD) + (geniCodeDivision): replaced (unsigned long) by (TYPE_UDWORD) + (geniCodeAdd): an array index will stay unsigned, even if promoted + from char to int + (geniCodeArray): ditto + * src/SDCCicode.h: made geniCodeCast() static: removed prototype + * src/SDCCsymt.c (computeType): added more support for char; + promotion of char is selectable by promoteCharToInt, fixed signedness + for all cases + (powof2): replaced (unsigned long) by (TYPE_UDWORD) + * src/SDCCsymt.h (powof2): replaced (unsigned long) by (TYPE_UDWORD) + * src/SDCCval (val*): replaced signedness calculation by + computeType() + rearranged if-branches (cosmetic) + (valShift): added warning W_SHIFT_CHANGED + (valCompare): fixed problem with different types + * src/hc08/rallo.c (leastUsedLR): fixed gcc 3.3 warning + * support/regression/tests/literalop.c: added many cases + * support/regression/tests/ast_constant_folding.c: changed finally to + 'unsigned int' + * .version: new year, new version: 2.3.7 + 2004-01-01 Erik Petrich * src/SDCCsymt.h: missing from yesterday's commits @@ -22,7 +51,7 @@ 2003-12-22 Frieder Ferlemann - * src/mcs51/gen.c (genPlus): added special handling for 256 byte + * src/mcs51/gen.c (genPlus): added special handling for 256 byte aligned xdata arrays. Erik helped me with the if clause. 2003-12-20 Erik Petrich @@ -104,8 +133,8 @@ 2003-12-13 Frieder Ferlemann - * src/mcs51/main.c: fixed bug #737001 for the mcs51. SDCC clears - xdata and data memory on startup. Set the environment variable + * src/mcs51/main.c: fixed bug #737001 for the mcs51. SDCC clears + xdata and data memory on startup. Set the environment variable SDCC_NOGENRAMCLEAR to disable this. * src/mcs51/peephole.def, * src/ds390/peephole.def: using the atomic test and clear instruction jbc diff --git a/src/SDCCast.c b/src/SDCCast.c index 7a8bfc61..6974206c 100644 --- a/src/SDCCast.c +++ b/src/SDCCast.c @@ -344,7 +344,7 @@ hasSEFcalls (ast * tree) /*-----------------------------------------------------------------*/ /* isAstEqual - compares two asts & returns 1 if they are equal */ /*-----------------------------------------------------------------*/ -int +static int isAstEqual (ast * t1, ast * t2) { if (!t1 && !t2) @@ -2382,7 +2382,7 @@ decorateType (ast * tree) } TTYPE (tree) = - computeType (LTYPE (tree), RTYPE (tree)); + computeType (LTYPE (tree), RTYPE (tree), FALSE); TETYPE (tree) = getSpec (TTYPE (tree)); /* if left is a literal exchange left & right */ @@ -2595,7 +2595,8 @@ decorateType (ast * tree) LRVAL (tree) = RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree))); + RTYPE (tree), + FALSE)); /*------------------------------------------------------------------*/ /*----------------------------*/ @@ -2623,7 +2624,8 @@ decorateType (ast * tree) LRVAL (tree) = RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree))); + RTYPE (tree), + TRUE)); /* if right is a literal and */ /* left is also a division by a literal then */ @@ -2688,7 +2690,8 @@ decorateType (ast * tree) LRVAL (tree) = RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree))); + RTYPE (tree), + TRUE)); return tree; /*------------------------------------------------------------------*/ @@ -2800,13 +2803,16 @@ decorateType (ast * tree) LRVAL (tree) = RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree))); + RTYPE (tree), + TRUE)); /* promote result to int if left & right are char this will facilitate hardware multiplies 8bit x 8bit = 16bit */ + /* now done by computeType if (IS_CHAR(LETYPE(tree)) && IS_CHAR(RETYPE(tree))) { SPEC_NOUN(TETYPE(tree)) = V_INT; } + */ return tree; @@ -2937,7 +2943,8 @@ decorateType (ast * tree) else TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree))); + RTYPE (tree), + FALSE)); return tree; /*------------------------------------------------------------------*/ @@ -3036,7 +3043,8 @@ decorateType (ast * tree) else TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree))); + RTYPE (tree), + FALSE)); LRVAL (tree) = RRVAL (tree) = 1; @@ -3459,16 +3467,18 @@ decorateType (ast * tree) } /* if unsigned value < 0 then always false */ /* if (unsigned value) > 0 then (unsigned value) */ - if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) && - ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) { - - if (tree->opval.op == '<') { + if (SPEC_USIGN(LETYPE(tree)) && IS_LITERAL(RTYPE(tree)) && + ((int) floatFromVal (valFromType (RETYPE (tree)))) == 0) + { + if (tree->opval.op == '<') + { return tree->right; - } - if (tree->opval.op == '>') { + } + if (tree->opval.op == '>') + { return tree->left; - } - } + } + } /* if they are both literal then */ /* rewrite the tree */ if (IS_LITERAL (RTYPE (tree)) && @@ -3607,7 +3617,7 @@ decorateType (ast * tree) goto errorTreeReturn; } - TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree)); + TTYPE (tree) = computeType (LTYPE (tree), RTYPE (tree), FALSE); TETYPE (tree) = getSpec (TTYPE (tree)); return tree; @@ -3689,7 +3699,8 @@ decorateType (ast * tree) RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree))); + RTYPE (tree), + FALSE)); if (!tree->initMode && IS_CONSTANT (LETYPE (tree))) werror (E_CODE_WRITE, "-="); @@ -3730,7 +3741,8 @@ decorateType (ast * tree) RRVAL (tree) = 1; TETYPE (tree) = getSpec (TTYPE (tree) = computeType (LTYPE (tree), - RTYPE (tree))); + RTYPE (tree), + FALSE)); if (!tree->initMode && IS_CONSTANT (LETYPE (tree))) werror (E_CODE_WRITE, "+="); @@ -5140,7 +5152,7 @@ void ast_print (ast * tree, FILE *outfile, int indent) fprintf(outfile,"%u", (TYPE_UDWORD) floatFromVal(tree->opval.val)); else fprintf(outfile,"%d", (TYPE_DWORD) floatFromVal(tree->opval.val)); - fprintf(outfile,", 0x%x, %g", (TYPE_UDWORD) floatFromVal(tree->opval.val), + fprintf(outfile,", 0x%x, %f", (TYPE_UDWORD) floatFromVal(tree->opval.val), floatFromVal(tree->opval.val)); } else if (tree->opval.val->sym) { /* if the undefined flag is set then give error message */ diff --git a/src/SDCCicode.c b/src/SDCCicode.c index b723c541..a6a2193a 100644 --- a/src/SDCCicode.c +++ b/src/SDCCicode.c @@ -53,6 +53,7 @@ operand *geniCodeRValue (operand *, bool); operand *geniCodeDerefPtr (operand *,int); int isLvaluereq(int lvl); void setOClass (sym_link * ptr, sym_link * spec); +static operand *geniCodeCast (sym_link *, operand *, bool); #define PRINTFUNC(x) void x (FILE *of, iCode *ic, char *s) /* forward definition of ic print functions */ @@ -144,14 +145,14 @@ void checkConstantRange(sym_link *ltype, value *val, char *msg, max = pow ((double)2.0, (double)bitsForType(ltype)); - if (SPEC_LONG(val->type)) { - if (SPEC_USIGN(val->type)) { + if (IS_LONG(val->type)) { + if (IS_UNSIGNED(val->type)) { v=SPEC_CVAL(val->type).v_ulong; } else { v=SPEC_CVAL(val->type).v_long; } } else { - if (SPEC_USIGN(val->type)) { + if (IS_UNSIGNED(val->type)) { v=SPEC_CVAL(val->type).v_uint; } else { v=SPEC_CVAL(val->type).v_int; @@ -165,21 +166,21 @@ void checkConstantRange(sym_link *ltype, value *val, char *msg, pedantic=2; #endif - if (SPEC_NOUN(ltype)==FLOAT) { + if (IS_FLOAT(ltype)) { // anything will do return; } - if (!SPEC_USIGN(val->type) && v<0) { + if (!IS_UNSIGNED(val->type) && v<0) { negative=1; - if (SPEC_USIGN(ltype) && (pedantic>1)) { + if (IS_UNSIGNED(ltype) && (pedantic>1)) { warnings++; } v=-v; } // if very pedantic: "char c=200" is not allowed - if (pedantic>1 && !SPEC_USIGN(ltype)) { + if (pedantic>1 && !IS_UNSIGNED(ltype)) { max = max/2 + negative; } @@ -190,7 +191,7 @@ void checkConstantRange(sym_link *ltype, value *val, char *msg, #if 0 // temporary disabled, leaving the warning as a reminder if (warnings) { SNPRINTF (message, sizeof(message), "for %s %s in %s", - SPEC_USIGN(ltype) ? "unsigned" : "signed", + IS_UNSIGNED(ltype) ? "unsigned" : "signed", nounName(ltype), msg); werror (W_CONST_RANGE, message); @@ -222,7 +223,7 @@ printOperand (operand * op, FILE * file) case VALUE: opetype = getSpec (operandType (op)); - if (SPEC_NOUN (opetype) == V_FLOAT) + if (IS_FLOAT (opetype)) fprintf (file, "%g {", SPEC_CVAL (opetype).v_float); else fprintf (file, "0x%x {", (unsigned) floatFromVal (op->operand.valOperand)); @@ -1065,7 +1066,7 @@ iCode *getBuiltinParms (iCode *ic, int *pcount, operand **parms) ic = ic->next; (*pcount)++; } - + ic->generated = 1; /* make sure this is a builtin function call */ assert(IS_SYMOP(IC_LEFT(ic))); @@ -1123,14 +1124,14 @@ operandOperation (operand * left, operand * right, !IS_SPEC (type)) { /* long is handled here, because it can overflow with double */ - if (SPEC_LONG (type) || + if (IS_LONG (type) || !IS_SPEC (type)) /* signed and unsigned mul are the same, as long as the precision of the result isn't bigger than the precision of the operands. */ retval = operandFromValue (valCastLiteral (type, (TYPE_UDWORD) operandLitValue (left) * (TYPE_UDWORD) operandLitValue (right))); - else if (SPEC_USIGN (type)) /* unsigned int */ + else if (IS_UNSIGNED (type)) /* unsigned int */ { /* unsigned int is handled here in order to detect overflow */ TYPE_UDWORD ul = (TYPE_UWORD) operandLitValue (left) * @@ -1165,23 +1166,35 @@ operandOperation (operand * left, operand * right, } else - retval = operandFromValue (valCastLiteral (type, - operandLitValue (left) / - operandLitValue (right))); + { + if (IS_UNSIGNED (type)) + { + SPEC_USIGN (let) = 1; + SPEC_USIGN (ret) = 1; + retval = operandFromValue (valCastLiteral (type, + (TYPE_UDWORD) operandLitValue (left) / + (TYPE_UDWORD) operandLitValue (right))); + } + else + { + retval = operandFromValue (valCastLiteral (type, + operandLitValue (left) / + operandLitValue (right))); + } + } break; case '%': - if ((TYPE_UDWORD) operandLitValue (right) == 0) { + if ((TYPE_UDWORD) operandLitValue (right) == 0) + { werror (E_DIVIDE_BY_ZERO); retval = right; - } + } else { - if (SPEC_USIGN(let) || SPEC_USIGN(ret)) - /* one of the operands is unsigned */ + if (IS_UNSIGNED (type)) retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) % (TYPE_UDWORD) operandLitValue (right)); else - /* both operands are signed */ retval = operandFromLit ((TYPE_DWORD) operandLitValue (left) % (TYPE_DWORD) operandLitValue (right)); } @@ -1195,7 +1208,7 @@ operandOperation (operand * left, operand * right, case RIGHT_OP: /* The number of right shifts is always unsigned. Signed doesn't make sense here. Shifting by a negative number is impossible. */ - if (SPEC_USIGN(let)) + if (IS_UNSIGNED(let)) /* unsigned: logic shift right */ retval = operandFromLit ((TYPE_UDWORD) operandLitValue (left) >> (TYPE_UDWORD) operandLitValue (right)); @@ -1210,14 +1223,14 @@ operandOperation (operand * left, operand * right, TYPE_UDWORD l, r; l = (TYPE_UDWORD) operandLitValue (left); - if (SPEC_NOUN(OP_VALUE(left)->type) == V_CHAR) + if (IS_CHAR(OP_VALUE(left)->type)) l &= 0xff; - else if (!SPEC_LONG (OP_VALUE(left)->type)) + else if (!IS_LONG (OP_VALUE(left)->type)) l &= 0xffff; r = (TYPE_UDWORD) operandLitValue (right); - if (SPEC_NOUN(OP_VALUE(right)->type) == V_CHAR) + if (IS_CHAR(OP_VALUE(right)->type)) r &= 0xff; - else if (!SPEC_LONG (OP_VALUE(right)->type)) + else if (!IS_LONG (OP_VALUE(right)->type)) r &= 0xffff; retval = operandFromLit (l == r); } @@ -1736,18 +1749,29 @@ usualUnaryConversions (operand * op) /*-----------------------------------------------------------------*/ /* perform "usual binary conversions" */ /*-----------------------------------------------------------------*/ -sym_link * -usualBinaryConversions (operand ** op1, operand ** op2) +static sym_link * +usualBinaryConversions (operand ** op1, operand ** op2, + bool promoteCharToInt, bool isMul) { sym_link *ctype; sym_link *rtype = operandType (*op2); sym_link *ltype = operandType (*op1); - - ctype = computeType (ltype, rtype); + + ctype = computeType (ltype, rtype, promoteCharToInt); + + /* special for multiplication: + This if for 'mul a,b', which takes two chars and returns an int */ + if ( isMul + /* && promoteCharToInt superfluous, already handled by computeType() */ + && IS_CHAR (getSpec (ltype)) + && IS_CHAR (getSpec (rtype)) + && !(IS_UNSIGNED (getSpec (rtype)) ^ IS_UNSIGNED (getSpec (ltype))) + && IS_INT (getSpec (ctype))) + return ctype; *op1 = geniCodeCast (ctype, *op1, TRUE); *op2 = geniCodeCast (ctype, *op2, TRUE); - + return ctype; } @@ -1812,7 +1836,7 @@ geniCodeRValue (operand * op, bool force) /*-----------------------------------------------------------------*/ /* geniCodeCast - changes the value from one type to another */ /*-----------------------------------------------------------------*/ -operand * +static operand * geniCodeCast (sym_link * type, operand * op, bool implicit) { iCode *ic; @@ -1834,14 +1858,16 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) /* if this is a literal then just change the type & return */ if (IS_LITERAL (opetype) && op->type == VALUE && !IS_PTR (type) && !IS_PTR (optype)) - return operandFromValue (valCastLiteral (type, - operandLitValue (op))); + { + return operandFromValue (valCastLiteral (type, + operandLitValue (op))); + } /* if casting to/from pointers, do some checking */ if (IS_PTR(type)) { // to a pointer if (!IS_PTR(optype) && !IS_FUNC(optype) && !IS_AGGREGATE(optype)) { // from a non pointer - if (IS_INTEGRAL(optype)) { - // maybe this is NULL, than it's ok. + if (IS_INTEGRAL(optype)) { + // maybe this is NULL, than it's ok. if (!(IS_LITERAL(optype) && (SPEC_CVAL(optype).v_ulong ==0))) { if (port->s.gptr_size > port->s.fptr_size && IS_GENPTR(type)) { // no way to set the storage @@ -1857,9 +1883,9 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) errors++; } } - } else { + } else { // shouldn't do that with float, array or structure unless to void - if (!IS_VOID(getSpec(type)) && + if (!IS_VOID(getSpec(type)) && !(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) { werror(E_INCOMPAT_TYPES); errors++; @@ -1869,7 +1895,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) if (port->s.gptr_size > port->s.fptr_size /*!TARGET_IS_Z80 && !TARGET_IS_GBZ80*/) { // if not a pointer to a function if (!(IS_CODEPTR(type) && IS_FUNC(type->next) && IS_FUNC(optype))) { - if (implicit) { // if not to generic, they have to match + if (implicit) { // if not to generic, they have to match if ((!IS_GENPTR(type) && (DCL_TYPE(optype) != DCL_TYPE(type)))) { werror(E_INCOMPAT_PTYPES); errors++; @@ -1903,11 +1929,10 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) ((IS_SPEC (type) && IS_SPEC (optype)) || (!IS_SPEC (type) && !IS_SPEC (optype)))) { - ic = newiCode ('=', NULL, op); IC_RESULT (ic) = newiTempOperand (type, 0); SPIL_LOC (IC_RESULT (ic)) = - (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL); + (IS_TRUE_SYMOP (op) ? OP_SYMBOL (op) : NULL); IC_RESULT (ic)->isaddr = 0; } else @@ -1932,7 +1957,7 @@ geniCodeCast (sym_link * type, operand * op, bool implicit) /*-----------------------------------------------------------------*/ /* geniCodeLabel - will create a Label */ /*-----------------------------------------------------------------*/ -void +void geniCodeLabel (symbol * label) { iCode *ic; @@ -1944,7 +1969,7 @@ geniCodeLabel (symbol * label) /*-----------------------------------------------------------------*/ /* geniCodeGoto - will create a Goto */ /*-----------------------------------------------------------------*/ -void +void geniCodeGoto (symbol * label) { iCode *ic; @@ -1957,7 +1982,7 @@ geniCodeGoto (symbol * label) /* geniCodeMultiply - gen intermediate code for multiplication */ /*-----------------------------------------------------------------*/ operand * -geniCodeMultiply (operand * left, operand * right,int resultIsInt) +geniCodeMultiply (operand * left, operand * right, int resultIsInt) { iCode *ic; int p2 = 0; @@ -1970,20 +1995,16 @@ geniCodeMultiply (operand * left, operand * right,int resultIsInt) right->operand.valOperand)); if (IS_LITERAL(retype)) { - p2 = powof2 ((unsigned long) floatFromVal (right->operand.valOperand)); + p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand)); } - resType = usualBinaryConversions (&left, &right); + resType = usualBinaryConversions (&left, &right, resultIsInt, TRUE); #if 1 rtype = operandType (right); retype = getSpec (rtype); ltype = operandType (left); letype = getSpec (ltype); #endif - if (resultIsInt) - { - SPEC_NOUN(getSpec(resType))=V_INT; - } /* if the right is a literal & power of 2 */ /* then make it a left shift */ @@ -2030,15 +2051,15 @@ geniCodeDivision (operand * left, operand * right) sym_link *ltype = operandType (left); sym_link *letype = getSpec (ltype); - resType = usualBinaryConversions (&left, &right); + resType = usualBinaryConversions (&left, &right, TRUE, FALSE); /* if the right is a literal & power of 2 and left is unsigned then make it a right shift */ if (IS_LITERAL (retype) && !IS_FLOAT (letype) && - SPEC_USIGN(letype) && - (p2 = powof2 ((unsigned long) + IS_UNSIGNED(letype) && + (p2 = powof2 ((TYPE_UDWORD) floatFromVal (right->operand.valOperand)))) { ic = newiCode (RIGHT_OP, left, operandFromLit (p2)); /* right shift */ } @@ -2069,7 +2090,7 @@ geniCodeModulus (operand * left, operand * right) return operandFromValue (valMod (left->operand.valOperand, right->operand.valOperand)); - resType = usualBinaryConversions (&left, &right); + resType = usualBinaryConversions (&left, &right, TRUE, FALSE); /* now they are the same size */ ic = newiCode ('%', left, right); @@ -2148,7 +2169,7 @@ geniCodeSubtract (operand * left, operand * right) } else { /* make them the same size */ - resType = usualBinaryConversions (&left, &right); + resType = usualBinaryConversions (&left, &right, FALSE, FALSE); } ic = newiCode ('-', left, right); @@ -2174,6 +2195,7 @@ geniCodeAdd (operand * left, operand * right, int lvl) sym_link *resType; operand *size; int isarray = 0; + bool indexUnsigned; LRTYPE; /* if the right side is LITERAL zero */ @@ -2190,15 +2212,22 @@ geniCodeAdd (operand * left, operand * right, int lvl) { isarray = left->isaddr; // there is no need to multiply with 1 - if (getSize(ltype->next)!=1) { - size = operandFromLit (getSize (ltype->next)); - right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE)); - } + if (getSize (ltype->next) != 1) + { + size = operandFromLit (getSize (ltype->next)); + indexUnsigned = IS_UNSIGNED (getSpec (operandType (right))); + right = geniCodeMultiply (right, size, (getArraySizePtr(left) >= INTSIZE)); + /* Even if right is a 'unsigned char', + the result will be a 'signed int' due to the promotion rules. + It doesn't make sense when accessing arrays, so let's fix it here: */ + if (indexUnsigned) + SPEC_USIGN (getSpec (operandType (right))) = 1; + } resType = copyLinkChain (ltype); } else { // make them the same size - resType = usualBinaryConversions (&left, &right); + resType = usualBinaryConversions (&left, &right, FALSE, FALSE); } /* if they are both literals then we know */ @@ -2270,20 +2299,24 @@ geniCodeArray (operand * left, operand * right,int lvl) { iCode *ic; sym_link *ltype = operandType (left); - + bool indexUnsigned; + if (IS_PTR (ltype)) { if (IS_PTR (ltype->next) && left->isaddr) { left = geniCodeRValue (left, FALSE); } - + return geniCodeDerefPtr (geniCodeAdd (left, right, lvl), lvl); } - + indexUnsigned = IS_UNSIGNED (getSpec (operandType (right))); right = geniCodeMultiply (right, operandFromLit (getSize (ltype->next)), (getArraySizePtr(left) >= INTSIZE)); - + /* Even if right is a 'unsigned char', the result will be a 'signed int' due to the promotion rules. + It doesn't make sense when accessing arrays, so let's fix it here: */ + if (indexUnsigned) + SPEC_USIGN (getSpec (operandType (right))) = 1; /* we can check for limits here */ if (isOperandLiteral (right) && IS_ARRAY (ltype) && @@ -2308,7 +2341,7 @@ geniCodeArray (operand * left, operand * right,int lvl) } /*-----------------------------------------------------------------*/ -/* geniCodeStruct - generates intermediate code for structres */ +/* geniCodeStruct - generates intermediate code for structures */ /*-----------------------------------------------------------------*/ operand * geniCodeStruct (operand * left, operand * right, bool islval) @@ -2779,7 +2812,7 @@ geniCodeLogic (operand * left, operand * right, int op) } } - ctype = usualBinaryConversions (&left, &right); + ctype = usualBinaryConversions (&left, &right, FALSE, FALSE); ic = newiCode (op, left, right); IC_RESULT (ic) = newiTempOperand (newCharLink (), 1); @@ -3347,7 +3380,7 @@ geniCodeJumpTable (operand * cond, value * caseVals, ast * tree) sym_link *cetype = getSpec (operandType (cond)); /* no need to check the lower bound if the condition is unsigned & minimum value is zero */ - if (!(min == 0 && SPEC_USIGN (cetype))) + if (!(min == 0 && IS_UNSIGNED (cetype))) { boundary = geniCodeLogic (cond, operandFromLit (min), '<'); ic = newiCodeCondition (boundary, falseLabel, NULL); diff --git a/src/SDCCicode.h b/src/SDCCicode.h index 8d6c543b..1822f79f 100644 --- a/src/SDCCicode.h +++ b/src/SDCCicode.h @@ -291,7 +291,6 @@ int isOperandVolatile (operand *, bool); int isOperandGlobal (operand *); void printiCChain (iCode *, FILE *); operand *ast2iCode (ast *,int); -operand *geniCodeCast (sym_link *, operand *, bool); operand *geniCodePtrPtrSubtract (operand *, operand *); void initiCode (); iCode *iCodeFromAst (ast *); diff --git a/src/SDCCsymt.c b/src/SDCCsymt.c index 14bcaee6..78d03f4f 100644 --- a/src/SDCCsymt.c +++ b/src/SDCCsymt.c @@ -1338,7 +1338,7 @@ checkSClass (symbol * sym, int isProto) } } } - + /* automatic symbols cannot be given */ /* an absolute address ignore it */ if (sym->level && @@ -1513,7 +1513,7 @@ cleanUpLevel (bucket ** table, int level) /* computeType - computes the resultant type from two types */ /*------------------------------------------------------------------*/ sym_link * -computeType (sym_link * type1, sym_link * type2) +computeType (sym_link * type1, sym_link * type2, bool promoteCharToInt) { sym_link *rType; sym_link *reType; @@ -1546,14 +1546,18 @@ computeType (sym_link * type1, sym_link * type2) rType = copyLinkChain (type2); reType = getSpec (rType); -#if 0 - if (SPEC_NOUN (reType) == V_CHAR) + + /* avoid conflicting types */ + reType->select.s._signed = 0; + + if (IS_CHAR (reType) && promoteCharToInt) SPEC_NOUN (reType) = V_INT; -#endif - /* if either of them unsigned but not val then make this unsigned */ - if ((SPEC_USIGN (etype1) || SPEC_USIGN (etype2)) && - !IS_FLOAT (reType)) + if ( ( ( SPEC_USIGN (etype1) + && (getSize (etype1) >= getSize (reType))) + || ( SPEC_USIGN (etype2) + && (getSize (etype2) >= getSize (reType)))) + && !IS_FLOAT (reType)) SPEC_USIGN (reType) = 1; else SPEC_USIGN (reType) = 0; @@ -2628,8 +2632,8 @@ printTypeChainRaw (sym_link * start, FILE * of) /*-----------------------------------------------------------------*/ /* powof2 - returns power of two for the number if number is pow 2 */ /*-----------------------------------------------------------------*/ -int -powof2 (unsigned long num) +int +powof2 (TYPE_UDWORD num) { int nshifts = 0; int n1s = 0; @@ -2672,7 +2676,7 @@ sym_link *floatType; static char * _mangleFunctionName(char *in) { - if (port->getMangledFunctionName) + if (port->getMangledFunctionName) { return port->getMangledFunctionName(in); } diff --git a/src/SDCCsymt.h b/src/SDCCsymt.h index 8632c163..f79b0493 100644 --- a/src/SDCCsymt.h +++ b/src/SDCCsymt.h @@ -539,10 +539,10 @@ int funcInChain (sym_link *); void addSymChain (symbol *); sym_link *structElemType (sym_link *, value *); symbol *getStructElement (structdef *, symbol *); -sym_link *computeType (sym_link *, sym_link *); +sym_link *computeType (sym_link *, sym_link *, bool promoteCharToInt); void processFuncArgs (symbol *); int isSymbolEqual (symbol *, symbol *); -int powof2 (unsigned long); +int powof2 (TYPE_UDWORD); void printTypeChain (sym_link *, FILE *); void printTypeChainRaw (sym_link *, FILE *); void initCSupport (); diff --git a/src/SDCCval.c b/src/SDCCval.c index fbbf0c11..7c0e04da 100644 --- a/src/SDCCval.c +++ b/src/SDCCval.c @@ -268,7 +268,7 @@ list2expr (initList * ilist) /*------------------------------------------------------------------*/ /* resolveIvalSym - resolve symbols in initial values */ /*------------------------------------------------------------------*/ -void +void resolveIvalSym (initList * ilist) { if (!ilist) @@ -374,7 +374,7 @@ static value *cheapestVal (value *val) { static value *cheapestVal (value *val) { - /* - signed/unsigned must no be changed. + /* - signed/unsigned must not be changed. - long must not be changed. the only possible reduction is from signed int to signed char, @@ -1088,18 +1088,9 @@ valMult (value * lval, value * rval) IS_FLOAT (rval->etype) ? V_FLOAT : V_INT); SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); - /* both signed char and unsigned char are promoted to signed int */ - if (IS_CHAR (lval->etype)) - { - SPEC_USIGN (lval->etype) = 0; - SPEC_NOUN (lval->etype) = V_INT; - } - if (IS_CHAR (rval->etype)) - { - SPEC_USIGN (rval->etype) = 0; - SPEC_NOUN (rval->etype) = V_INT; - } - SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype)); + SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype, + rval->etype, + TRUE)); if (IS_FLOAT (val->type)) SPEC_CVAL (val->type).v_float = floatFromVal (lval) * floatFromVal (rval); /* signed and unsigned mul are the same, as long as the precision of the @@ -1107,7 +1098,7 @@ valMult (value * lval, value * rval) else if (SPEC_LONG (val->type)) SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) * (TYPE_UDWORD) floatFromVal (rval); - else if (SPEC_USIGN (val->type)) /* unsigned */ + else if (SPEC_USIGN (val->type)) /* unsigned int */ { TYPE_UDWORD ul = (TYPE_UWORD) floatFromVal (lval) * (TYPE_UWORD) floatFromVal (rval); @@ -1116,7 +1107,7 @@ valMult (value * lval, value * rval) if (ul != (TYPE_UWORD) ul) werror (W_INT_OVL); } - else /* int */ + else /* signed int */ { TYPE_DWORD l = (TYPE_WORD) floatFromVal (lval) * (TYPE_WORD) floatFromVal (rval); @@ -1125,7 +1116,7 @@ valMult (value * lval, value * rval) if (l != (TYPE_WORD) l) werror (W_INT_OVL); } - return cheapestVal(val); + return cheapestVal (val); } /*------------------------------------------------------------------*/ @@ -1148,45 +1139,32 @@ valDiv (value * lval, value * rval) SPEC_NOUN (val->type) = (IS_FLOAT (lval->etype) || IS_FLOAT (rval->etype) ? V_FLOAT : V_INT); SPEC_SCLS (val->etype) = S_LITERAL; - /* both signed char and unsigned char are promoted to signed int */ - if (IS_CHAR (lval->etype)) - { - SPEC_USIGN (lval->etype) = 0; - SPEC_NOUN (lval->etype) = V_INT; - } - if (IS_CHAR (rval->etype)) - { - SPEC_USIGN (rval->etype) = 0; - SPEC_NOUN (rval->etype) = V_INT; - } - SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype)); SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); + SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype, + rval->etype, + TRUE)); if (IS_FLOAT (val->type)) SPEC_CVAL (val->type).v_float = floatFromVal (lval) / floatFromVal (rval); + else if (SPEC_LONG (val->type)) + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) / + (TYPE_UDWORD) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) / + (TYPE_DWORD) floatFromVal (rval); + } else { - if (SPEC_LONG (val->type)) - { - if (SPEC_USIGN (val->type)) - SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) / - (TYPE_UDWORD) floatFromVal (rval); - else - SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) / - (TYPE_DWORD) floatFromVal (rval); - } + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) / + (TYPE_UWORD) floatFromVal (rval); else - { - if (SPEC_USIGN (val->type)) { - SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) / - (TYPE_UWORD) floatFromVal (rval); - } else { - SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) / - (TYPE_WORD) floatFromVal (rval); - } - } + SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) / + (TYPE_WORD) floatFromVal (rval); } - return cheapestVal(val); + return cheapestVal (val); } /*------------------------------------------------------------------*/ @@ -1202,8 +1180,10 @@ valMod (value * lval, value * rval) val->type = val->etype = newLink (SPECIFIER); SPEC_NOUN (val->type) = V_INT; /* type is int */ SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ - SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype)); SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); + SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype, + rval->etype, + TRUE)); if (SPEC_LONG (val->type)) { @@ -1216,16 +1196,14 @@ valMod (value * lval, value * rval) } else { - if (SPEC_USIGN (val->type)) { - SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) % - (TYPE_UWORD) floatFromVal (rval); - } else { - SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) % - (TYPE_WORD) floatFromVal (rval); - } + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) % + (TYPE_UWORD) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) % + (TYPE_WORD) floatFromVal (rval); } - - return cheapestVal(val); + return cheapestVal (val); } /*------------------------------------------------------------------*/ @@ -1243,43 +1221,30 @@ valPlus (value * lval, value * rval) IS_FLOAT (rval->etype) ? V_FLOAT : V_INT); SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); - /* both signed char and unsigned char are promoted to signed int */ - if (IS_CHAR (lval->etype)) - { - SPEC_USIGN (lval->etype) = 0; - SPEC_NOUN (lval->etype) = V_INT; - } - if (IS_CHAR (rval->etype)) - { - SPEC_USIGN (rval->etype) = 0; - SPEC_NOUN (rval->etype) = V_INT; - } - SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype)); + SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype, + rval->etype, + TRUE)); if (IS_FLOAT (val->type)) SPEC_CVAL (val->type).v_float = floatFromVal (lval) + floatFromVal (rval); + else if (SPEC_LONG (val->type)) + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) + + (TYPE_UDWORD) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) + + (TYPE_DWORD) floatFromVal (rval); + } else { - if (SPEC_LONG (val->type)) - { - if (SPEC_USIGN (val->type)) - SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) + - (TYPE_UDWORD) floatFromVal (rval); - else - SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) + - (TYPE_DWORD) floatFromVal (rval); - } + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) + + (TYPE_UWORD) floatFromVal (rval); else - { - if (SPEC_USIGN (val->type)) { - SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) + - (TYPE_UWORD) floatFromVal (rval); - } else { - SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) + - (TYPE_WORD) floatFromVal (rval); - } - } + SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) + + (TYPE_WORD) floatFromVal (rval); } - return cheapestVal(val); + return cheapestVal (val); } /*------------------------------------------------------------------*/ @@ -1297,43 +1262,30 @@ valMinus (value * lval, value * rval) IS_FLOAT (rval->etype) ? V_FLOAT : V_INT); SPEC_SCLS (val->type) = S_LITERAL; /* will remain literal */ SPEC_LONG (val->type) = (SPEC_LONG (lval->etype) | SPEC_LONG (rval->etype)); - /* both signed char and unsigned char are promoted to signed int */ - if (IS_CHAR (lval->etype)) - { - SPEC_USIGN (lval->etype) = 0; - SPEC_NOUN (lval->etype) = V_INT; - } - if (IS_CHAR (rval->etype)) - { - SPEC_USIGN (rval->etype) = 0; - SPEC_NOUN (rval->etype) = V_INT; - } - SPEC_USIGN (val->type) = (SPEC_USIGN (lval->etype) | SPEC_USIGN (rval->etype)); + SPEC_USIGN (val->type) = SPEC_USIGN (computeType (lval->etype, + rval->etype, + FALSE)); if (IS_FLOAT (val->type)) SPEC_CVAL (val->type).v_float = floatFromVal (lval) - floatFromVal (rval); - else + else if (SPEC_LONG (val->type)) { - if (SPEC_LONG (val->type)) - { - if (SPEC_USIGN (val->type)) - SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) - - (TYPE_UDWORD) floatFromVal (rval); - else - SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) - - (TYPE_DWORD) floatFromVal (rval); - } + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_ulong = (TYPE_UDWORD) floatFromVal (lval) - + (TYPE_UDWORD) floatFromVal (rval); else - { - if (SPEC_USIGN (val->type)) { - SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) - - (TYPE_UWORD) floatFromVal (rval); - } else { - SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) - - (TYPE_WORD) floatFromVal (rval); - } - } + SPEC_CVAL (val->type).v_long = (TYPE_DWORD) floatFromVal (lval) - + (TYPE_DWORD) floatFromVal (rval); } - return cheapestVal(val); + else + { + if (SPEC_USIGN (val->type)) + SPEC_CVAL (val->type).v_uint = (TYPE_UWORD) floatFromVal (lval) - + (TYPE_UWORD) floatFromVal (rval); + else + SPEC_CVAL (val->type).v_int = (TYPE_WORD) floatFromVal (lval) - + (TYPE_WORD) floatFromVal (rval); + } + return cheapestVal (val); } /*------------------------------------------------------------------*/ @@ -1354,6 +1306,15 @@ valShift (value * lval, value * rval, int lr) SPEC_USIGN (val->type) = SPEC_USIGN (lval->etype); SPEC_LONG (val->type) = SPEC_LONG (lval->etype); + if (getSize (lval->type) * 8 <= (TYPE_UDWORD) floatFromVal (rval) && + /* left shift */ + (lr || + /* right shift and unsigned */ + (!lr && SPEC_USIGN (rval->type)))) + { + werror (W_SHIFT_CHANGED, (lr ? "left" : "right")); + } + if (SPEC_LONG (val->type)) { if (SPEC_USIGN (val->type)) @@ -1384,7 +1345,7 @@ valShift (value * lval, value * rval, int lr) (TYPE_WORD) floatFromVal (lval) >> (TYPE_UWORD) floatFromVal (rval); } } - return cheapestVal(val); + return cheapestVal (val); } /*------------------------------------------------------------------*/ @@ -1433,17 +1394,18 @@ valCompare (value * lval, value * rval, int ctype) TYPE_UDWORD l, r; l = (TYPE_UDWORD) floatFromVal (lval); - if (SPEC_NOUN(lval->type) == V_CHAR) - l &= 0xffff; /* promote to int */ - else if (!SPEC_LONG (lval->type)) - l &= 0xffff; - r = (TYPE_UDWORD) floatFromVal (rval); - if (SPEC_NOUN(rval->type) == V_CHAR) - r &= 0xffff; /* promote to int */ - else if (!SPEC_LONG (rval->type)) - r &= 0xffff; - + /* In order to correctly compare 'signed int' and 'unsigned int' it's + neccessary to strip them to 16 bit. + Literals are reduced to their cheapest type, therefore left and + right might have different types. It's neccessary to find a + common type: int (used for char too) or long */ + if (!IS_LONG (lval->etype) && + !IS_LONG (rval->etype)) + { + r = (TYPE_UWORD) r; + l = (TYPE_UWORD) l; + } SPEC_CVAL (val->type).v_int = l == r; } break; @@ -1459,17 +1421,18 @@ valCompare (value * lval, value * rval, int ctype) TYPE_UDWORD l, r; l = (TYPE_UDWORD) floatFromVal (lval); - if (SPEC_NOUN(lval->type) == V_CHAR) - l &= 0xffff; /* promote to int */ - else if (!SPEC_LONG (lval->type)) - l &= 0xffff; - r = (TYPE_UDWORD) floatFromVal (rval); - if (SPEC_NOUN(rval->type) == V_CHAR) - r &= 0xffff; /* promote to int */ - else if (!SPEC_LONG (rval->type)) - r &= 0xffff; - + /* In order to correctly compare 'signed int' and 'unsigned int' it's + neccessary to strip them to 16 bit. + Literals are reduced to their cheapest type, therefore left and + right might have different types. It's neccessary to find a + common type: int (used for char too) or long */ + if (!IS_LONG (lval->etype) && + !IS_LONG (rval->etype)) + { + r = (TYPE_UWORD) r; + l = (TYPE_UWORD) l; + } SPEC_CVAL (val->type).v_int = l != r; } break; diff --git a/src/hc08/ralloc.c b/src/hc08/ralloc.c index 82abbb0f..f413f765 100644 --- a/src/hc08/ralloc.c +++ b/src/hc08/ralloc.c @@ -434,7 +434,7 @@ leastUsedLR (set * sset) } - setToNull ((void **) &sset); + setToNull ((void *) &sset); sym->blockSpil = 0; return sym; } diff --git a/support/regression/tests/ast_constant_folding.c b/support/regression/tests/ast_constant_folding.c index aaec505e..66767afe 100644 --- a/support/regression/tests/ast_constant_folding.c +++ b/support/regression/tests/ast_constant_folding.c @@ -48,7 +48,7 @@ foo_mul (void) unsigned foo_div (void) { - return 33971 / i / 5 / i / i / 12; + return 33971u / i / 5 / i / i / 12; } unsigned diff --git a/support/regression/tests/literalop.c b/support/regression/tests/literalop.c index e66585dd..08800c14 100644 --- a/support/regression/tests/literalop.c +++ b/support/regression/tests/literalop.c @@ -14,8 +14,6 @@ typedef signed {type} stype; typedef unsigned {type} utype; -#define _{type} - #if defined(PORT_HOST) || defined(SDCC_z80) || defined(SDCC_gbz80) # define idata # define code @@ -23,9 +21,9 @@ typedef unsigned {type} utype; volatile char is8 = 8; -signed char sc; -signed short ss; -signed LONG sl; + signed char sc; + signed short ss; + signed LONG sl; unsigned char uc; unsigned short us; unsigned LONG ul; @@ -45,7 +43,33 @@ unsigned LONG t1, t2; void testOpOp(void) { - /* mul ast */ + /* mul signedness: usualBinaryConversions() */ + vsc = 0x7f; + vuc = 0xfe; + + sc = vsc * vsc; + ASSERT(sc == 1); + sc = vuc * vsc; + ASSERT(sc == 2); + sc = vuc * vuc; + ASSERT(sc == 4); + + ss = vsc * vsc; + ASSERT(ss == 0x3f01); + ss = vuc * vsc; + ASSERT(ss == 0x7e02); + ss = vuc * vuc; + ASSERT(ss == (short) 0xfc04); + /* after promotion the result of the multiplication is 'signed int', which overflows! */ + if (sizeof (int) == 2) + ASSERT(vuc * vuc < 1); + else + { + vus = 0xfffe; + ASSERT(vus * vus < 1); + } + + /* mul ast: valMult() */ ASSERT((stype) -3 * (stype) -1 == (stype) 3); ASSERT((stype) -3 * (stype) 1 == (stype) -3); ASSERT((stype) 3 * (stype) -1 == (stype) -3); @@ -77,11 +101,17 @@ testOpOp(void) ASSERT(1 * 40000 * is8 == 320000); /* LONG */ ASSERT(1 * 0x4000 * is8 == (sizeof(int) == 2 ? 0 : 0x20000)); /* unsigned */ - ASSERT(-1 * 1 < 0); - ASSERT(-1 * 1u > 0); - - - /* mul icode */ + ASSERT(-2 * 1 < 1); /* comparison with 0 is optimized, so let's use 1 instead */ + ASSERT(-2 * 1u > 1); + ASSERT(0x7fffu * 2 > 1); + ASSERT(0x7fffffffu * 2 > 1); + if (sizeof (int) == 2) + ASSERT(0x7fff * (unsigned char) 2 < 1); + else + ASSERT(0x7fffffff * (unsigned char) 2 < 1); + ASSERT(0x7fffffff * (unsigned short) 2 < 1); + + /* mul icode: operandOperation() */ s = -3; ASSERT(s * (stype) -1 == (stype) 3); ASSERT(s * (stype) 1 == (stype) -3); @@ -108,26 +138,85 @@ testOpOp(void) ASSERT((signed short) -2 * (unsigned short) 0x8004 == (sizeof(int) == 2 ? 0xfff8 : 0xfffefff8)); ASSERT((signed LONG ) -2 * (unsigned LONG ) 0x8004 == 0xfffefff8); - - + /* div ast: valDiv() */ ASSERT((stype) -12 / (stype) -3 == (stype) 4); ASSERT((stype) -12 / (stype) 3 == (stype) -4); ASSERT((stype) 12 / (stype) -3 == (stype) -4); -// ASSERT((stype) -12 / (utype) -3 == (stype) 4); -// ASSERT((utype) -12 / (stype) -3 == (stype) 4); -// ASSERT((utype) -12 / (utype) -3 == (stype) 4); + ASSERT((unsigned char ) -12 / (signed char ) -3 == (sizeof(int) == 2 ? 0xffaf : 0xffffffaf)); + ASSERT((unsigned short) -12 / (signed short) -3 == (sizeof(int) == 2 ? 0 : 0xffffaaaf)); + ASSERT((unsigned LONG ) -12 / (signed LONG ) -3 == 0); + ASSERT((utype) -12 / (stype) 3 == (stype) 0x55555551); + ASSERT((unsigned char ) 12 / (signed char ) -3 == -4); + ASSERT((unsigned short) 12 / (signed short) -3 == (sizeof(int) == 2 ? 0 : 0xfffffffc)); + ASSERT((unsigned LONG ) 12 / (signed LONG ) -3 == 0); + ASSERT((stype) -12 / (utype) -3 == 0); + ASSERT((signed char ) -12 / (unsigned char ) 3 == -4); + ASSERT((signed short) -12 / (unsigned short) 3 == (sizeof(int) == 2 ? 0x5551 : -4)); + ASSERT((signed LONG ) -12 / (unsigned LONG ) 3 == 0x55555551); + ASSERT((stype) 12 / (utype) -3 == 0); ASSERT(12u / 3 * 10000 == 40000); ASSERT(-1 / 1 < 0); + /* div icode: operandOperation() */ + s = -12; + ASSERT(s / (stype) -3 == (stype) 4); + s = -12; + ASSERT(s / (stype) 3 == (stype) -4); + s = 12; + ASSERT(s / (stype) -3 == (stype) -4); + + uc = -12; + ASSERT(uc / (signed char ) -3 == (sizeof(int) == 2 ? 0xffaf : 0xffffffaf)); + us = -12; + ASSERT(us / (signed short) -3 == (sizeof(int) == 2 ? 0 : 0xffffaaaf)); + ul = -12; + ASSERT(ul / (signed LONG ) -3 == 0); + u = -12; + ASSERT(u / (stype) 3 == (stype) 0x55555551); + uc = 12; + ASSERT(uc / (signed char ) -3 == -4); + us = 12; + ASSERT(us / (signed short) -3 == (sizeof(int) == 2 ? 0 : 0xfffffffc)); + ul = 12; + ASSERT(ul / (signed LONG ) -3 == 0); + + s = -12; + ASSERT(s / (utype) -3 == 0); + sc = -12; + ASSERT(sc / (unsigned char ) 3 == -4); + ss = -12; + ASSERT(ss / (unsigned short) 3 == (sizeof(int) == 2 ? 0x5551 : -4)); + sl = -12; + ASSERT(sl / (unsigned LONG ) 3 == 0x55555551); + s = 12; + ASSERT(s / (utype) -3 == 0); + + + /* mod ast: valMod() */ + /* -11 : 0xfff5 */ + /* -17 : 0xffef */ + ASSERT((stype) -17 % (stype) -11 == (stype) -6); + ASSERT((stype) -17 % (stype) 11 == (stype) -6); + ASSERT((stype) 17 % (stype) -11 == (stype) 6); + ASSERT((unsigned char ) -17 % (signed char ) -11 == 8); + ASSERT((unsigned short) -17 % (signed short) -11 == (sizeof(int) == 2 ? -17 : 3)); + ASSERT((unsigned LONG ) -17 % (signed LONG ) -11 == -17); + ASSERT((unsigned char ) -17 % (signed char ) 11 == 8); + ASSERT((unsigned short) -17 % (signed short) 11 == 3); + ASSERT((unsigned LONG ) -17 % (signed LONG ) 11 == 9); + ASSERT((unsigned char ) 17 % (signed char ) -11 == 6); + ASSERT((unsigned short) 17 % (signed short) -11 == (sizeof(int) == 2 ? 17 : 6)); + ASSERT((unsigned LONG ) 17 % (signed LONG ) -11 == 17); + ASSERT(-3 % 2 < 0); - ASSERT((stype) -14 % (stype) -3 == (stype) -2); - ASSERT((stype) -14 % (stype) 3 == (stype) -2); - ASSERT((stype) 14 % (stype) -3 == (stype) 2); - ASSERT(-3 % 2 < 0); + /* add */ + ASSERT( 80 + 80 == 160); + ASSERT(150 + 150 == 300); + ASSERT(160u + 160u == 320); }