+ Expression nbExp = GetNonBracketsExp(exp);
+ bool skipWarning = false;
+ TypeKind kind = exp.destType.kind;
+ if(nbExp.type == conditionExp && nbExp.destType && !nbExp.destType.casted && nbExp.destType.kind == exp.destType.kind)
+ // The if/else operands have already been checked / warned about
+ skipWarning = true;
+ if((kind == charType || kind == shortType) && exp.destType.isSigned == exp.expType.signedBeforePromotion && nbExp.type == opExp && nbExp.op.exp1 && nbExp.op.exp2)
+ {
+ int op = nbExp.op.op;
+ Expression nbExp1, nbExp2;
+ TypeKind from;
+
+ switch(op)
+ {
+ case '%': case '/':
+ nbExp1 = GetNonBracketsExp(nbExp.op.exp1);
+ from = nbExp1.expType.promotedFrom;
+ // Division and Modulo will not take more room than type before promotion
+ if(from == charType || (kind == shortType && from == shortType))
+ skipWarning = true;
+ break;
+ // Left shift
+ case LEFT_OP: case RIGHT_OP:
+ nbExp1 = GetNonBracketsExp(nbExp.op.exp1);
+ nbExp2 = GetNonBracketsExp(nbExp.op.exp2);
+ from = nbExp1.expType.promotedFrom;
+ // Right shift will not take more room than type before promotion
+ if(op == RIGHT_OP && (from == charType || (kind == shortType && from == shortType)))
+ skipWarning = true;
+ else if(nbExp2.isConstant && nbExp2.type == constantExp && (nbExp.op.op == RIGHT_OP || nbExp1.expType.bitMemberSize))
+ {
+ int n = (int)strtol(nbExp2.constant, null, 0);
+ int s = from == charType ? 8 : 16;
+ // Left shifting a bit member constrained in size may still fit in type before promotion
+ if(nbExp1.expType.bitMemberSize && nbExp1.expType.bitMemberSize < s)
+ s = nbExp1.expType.bitMemberSize;
+
+ // If right shifted enough things will fit in smaller type
+ if(nbExp.op.op == RIGHT_OP)
+ s -= n;
+ else
+ s += n;
+ if(s <= (kind == charType ? 8 : 16))
+ skipWarning = true;
+ }
+ break;
+ case '-':
+ if(!exp.destType.isSigned)
+ {
+ nbExp1 = GetNonBracketsExp(nbExp.op.exp1);
+ nbExp2 = GetNonBracketsExp(nbExp.op.exp2);
+ from = nbExp2.expType.promotedFrom;
+ // Max value of unsigned type before promotion minus the same will always fit
+ if((from == charType || from == shortType) && nbExp1.isConstant && nbExp1.type == constantExp)
+ {
+ int n = (int)strtol(nbExp1.constant, null, 0);
+ if(n == (from == charType ? 255 : 65535))
+ skipWarning = true;
+ }
+ }
+ break;
+ case '|':
+ {
+ TypeKind kind1, kind2;
+ nbExp1 = GetNonBracketsExp(nbExp.op.exp1);
+ nbExp2 = GetNonBracketsExp(nbExp.op.exp2);
+ kind1 = nbExp1.expType.promotedFrom ? nbExp1.expType.promotedFrom : nbExp1.expType.kind;
+ kind2 = nbExp2.expType.promotedFrom ? nbExp2.expType.promotedFrom : nbExp2.expType.kind;
+ if(((kind1 == charType || (kind1 == shortType && kind == shortType)) || MatchTypeExpression(nbExp1, exp.destType, null, false, false)) &&
+ ((kind2 == charType || (kind2 == shortType && kind == shortType)) || MatchTypeExpression(nbExp2, exp.destType, null, false, false)))
+ skipWarning = true;
+ break;
+ }
+ case '&':
+ {
+ TypeKind kind1, kind2;
+ nbExp1 = GetNonBracketsExp(nbExp.op.exp1);
+ nbExp2 = GetNonBracketsExp(nbExp.op.exp2);
+ kind1 = nbExp1.expType.promotedFrom ? nbExp1.expType.promotedFrom : nbExp1.expType.kind;
+ kind2 = nbExp2.expType.promotedFrom ? nbExp2.expType.promotedFrom : nbExp2.expType.kind;
+ if(((kind1 == charType || (kind1 == shortType && kind == shortType)) || MatchTypeExpression(nbExp1, exp.destType, null, false, false)) ||
+ ((kind2 == charType || (kind2 == shortType && kind == shortType)) || MatchTypeExpression(nbExp2, exp.destType, null, false, false)))
+ skipWarning = true;
+ break;
+ }
+ }
+ }
+
+ if(!skipWarning)
+ {
+ char expString[10240];
+ expString[0] = '\0';
+ if(inCompiler) { PrintExpression(exp, expString); ChangeCh(expString, '\n', ' '); }