Added utility functions to acquire bit width of types.
This commit is contained in:
@@ -315,19 +315,37 @@ static void OpAssignBitField (const GenDesc* Gen, ExprDesc* Expr, const char* Op
|
||||
} else if (Gen->Func == g_sub) {
|
||||
g_dec (Flags | CF_CONST, Expr2.IVal);
|
||||
} else {
|
||||
if (Expr2.IVal == 0) {
|
||||
/* Check for div by zero/mod by zero */
|
||||
if (Gen->Func == g_div) {
|
||||
Error ("Division by zero");
|
||||
} else if (Gen->Func == g_mod) {
|
||||
Error ("Modulo operation with zero");
|
||||
}
|
||||
} else if (Gen->Func == g_asl || Gen->Func == g_asr) {
|
||||
if (Expr2.IVal < 0) {
|
||||
Warning ("Shift count '%ld' is negative", Expr2.IVal);
|
||||
} else if (Expr2.IVal >= (long)(SizeOf (Expr->Type) * 8)) {
|
||||
Warning ("Shift count '%ld' >= width of type", Expr2.IVal);
|
||||
}
|
||||
if (!ED_IsUneval (Expr)) {
|
||||
if (Expr2.IVal == 0) {
|
||||
/* Check for div by zero/mod by zero */
|
||||
if (Gen->Func == g_div) {
|
||||
Error ("Division by zero");
|
||||
} else if (Gen->Func == g_mod) {
|
||||
Error ("Modulo operation with zero");
|
||||
}
|
||||
} else if (Gen->Func == g_asl || Gen->Func == g_asr) {
|
||||
const Type* CalType = IntPromotion (Expr->Type);
|
||||
unsigned ExprBits = BitSizeOf (CalType);
|
||||
|
||||
/* If the shift count is greater than or equal to the width of the
|
||||
** promoted left operand, the behaviour is undefined according to
|
||||
** the standard.
|
||||
*/
|
||||
if (Expr2.IVal < 0) {
|
||||
Warning ("Negative shift count %ld treated as %u for %s",
|
||||
Expr2.IVal,
|
||||
(unsigned)Expr2.IVal & (ExprBits - 1),
|
||||
GetBasicTypeName (CalType));
|
||||
} else if (Expr2.IVal >= (long)ExprBits) {
|
||||
Warning ("Shift count %ld >= width of %s treated as %u",
|
||||
Expr2.IVal,
|
||||
GetBasicTypeName (CalType),
|
||||
(unsigned)Expr2.IVal & (ExprBits - 1));
|
||||
}
|
||||
|
||||
/* Here we simply "wrap" the shift count around the width */
|
||||
Expr2.IVal &= ExprBits - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Adjust the types of the operands if needed */
|
||||
@@ -501,18 +519,36 @@ static void OpAssignArithmetic (const GenDesc* Gen, ExprDesc* Expr, const char*
|
||||
} else if (Gen->Func == g_sub) {
|
||||
g_dec (Flags | CF_CONST, Expr2.IVal);
|
||||
} else {
|
||||
if (Expr2.IVal == 0) {
|
||||
/* Check for div by zero/mod by zero */
|
||||
if (Gen->Func == g_div) {
|
||||
Error ("Division by zero");
|
||||
} else if (Gen->Func == g_mod) {
|
||||
Error ("Modulo operation with zero");
|
||||
}
|
||||
} else if (Gen->Func == g_asl || Gen->Func == g_asr) {
|
||||
if (Expr2.IVal < 0) {
|
||||
Warning ("Shift count '%ld' is negative", Expr2.IVal);
|
||||
} else if (Expr2.IVal >= (long)(SizeOf (Expr->Type) * 8)) {
|
||||
Warning ("Shift count '%ld' >= width of type", Expr2.IVal);
|
||||
if (!ED_IsUneval (Expr)) {
|
||||
if (Expr2.IVal == 0 && !ED_IsUneval (Expr)) {
|
||||
/* Check for div by zero/mod by zero */
|
||||
if (Gen->Func == g_div) {
|
||||
Error ("Division by zero");
|
||||
} else if (Gen->Func == g_mod) {
|
||||
Error ("Modulo operation with zero");
|
||||
}
|
||||
} else if (Gen->Func == g_asl || Gen->Func == g_asr) {
|
||||
const Type* CalType = IntPromotion (Expr->Type);
|
||||
unsigned ExprBits = BitSizeOf (CalType);
|
||||
|
||||
/* If the shift count is greater than or equal to the width of the
|
||||
** promoted left operand, the behaviour is undefined according to
|
||||
** the standard.
|
||||
*/
|
||||
if (Expr2.IVal < 0) {
|
||||
Warning ("Negative shift count %ld treated as %u for %s",
|
||||
Expr2.IVal,
|
||||
(unsigned)Expr2.IVal & (ExprBits - 1),
|
||||
GetBasicTypeName (CalType));
|
||||
} else if (Expr2.IVal >= (long)ExprBits) {
|
||||
Warning ("Shift count %ld >= width of %s treated as %u",
|
||||
Expr2.IVal,
|
||||
GetBasicTypeName (CalType),
|
||||
(unsigned)Expr2.IVal & (ExprBits - 1));
|
||||
}
|
||||
|
||||
/* Here we simply "wrap" the shift count around the width */
|
||||
Expr2.IVal &= ExprBits - 1;
|
||||
}
|
||||
}
|
||||
Gen->Func (Flags | CF_CONST, Expr2.IVal);
|
||||
|
||||
Reference in New Issue
Block a user