forked from OSchip/llvm-project
Sema: show shift result in hexadecimal
Change the output for -Wshift-overflow and -Wshift-sign-overflow to an unsigned hexadecimal. It makes more sense for looking at bits than a signed decimal does. Also, change the diagnostic's wording from "overrides" to "sets". This uses a new optional argument in APInt::toString() that adds the '0x' prefix to hexademical numbers. This fixes PR 9651. Patch by nobled@dreamwidth.org! llvm-svn: 133033
This commit is contained in:
parent
b05f02e956
commit
70f05fdfee
|
@ -2566,11 +2566,11 @@ def warn_remainder_by_zero : Warning<"remainder by zero is undefined">;
|
|||
def warn_shift_negative : Warning<"shift count is negative">;
|
||||
def warn_shift_gt_typewidth : Warning<"shift count >= width of type">;
|
||||
def warn_shift_result_gt_typewidth : Warning<
|
||||
"shift result (%0) requires %1 bits to represent, but %2 only has %3 bits">,
|
||||
InGroup<DiagGroup<"shift-overflow">>;
|
||||
def warn_shift_result_overrides_sign_bit : Warning<
|
||||
"shift result (%0) overrides the sign bit of the shift expression's type "
|
||||
"(%1) and becomes negative">,
|
||||
"signed shift result (%0) requires %1 bits to represent, but %2 only has "
|
||||
"%3 bits">, InGroup<DiagGroup<"shift-overflow">>;
|
||||
def warn_shift_result_sets_sign_bit : Warning<
|
||||
"signed shift result (%0) sets the sign bit of the shift expression's "
|
||||
"type (%1) and becomes negative">,
|
||||
InGroup<DiagGroup<"shift-sign-overflow">>, DefaultIgnore;
|
||||
|
||||
def warn_precedence_bitwise_rel : Warning<
|
||||
|
|
|
@ -7394,19 +7394,24 @@ static void DiagnoseBadShiftValues(Sema& S, ExprResult &lex, ExprResult &rex,
|
|||
llvm::APSInt Result = Left.extend(ResultBits.getLimitedValue());
|
||||
Result = Result.shl(Right);
|
||||
|
||||
// Print the bit representation of the signed integer as an unsigned
|
||||
// hexadecimal number.
|
||||
llvm::SmallString<40> HexResult;
|
||||
Result.toString(HexResult, 16, /*Signed =*/false, /*Literal =*/true);
|
||||
|
||||
// If we are only missing a sign bit, this is less likely to result in actual
|
||||
// bugs -- if the result is cast back to an unsigned type, it will have the
|
||||
// expected value. Thus we place this behind a different warning that can be
|
||||
// turned off separately if needed.
|
||||
if (LeftBits == ResultBits - 1) {
|
||||
S.Diag(Loc, diag::warn_shift_result_overrides_sign_bit)
|
||||
<< Result.toString(10) << LHSTy
|
||||
S.Diag(Loc, diag::warn_shift_result_sets_sign_bit)
|
||||
<< HexResult.str() << LHSTy
|
||||
<< lex.get()->getSourceRange() << rex.get()->getSourceRange();
|
||||
return;
|
||||
}
|
||||
|
||||
S.Diag(Loc, diag::warn_shift_result_gt_typewidth)
|
||||
<< Result.toString(10) << Result.getMinSignedBits() << LHSTy
|
||||
<< HexResult.str() << Result.getMinSignedBits() << LHSTy
|
||||
<< Left.getBitWidth() << lex.get()->getSourceRange() << rex.get()->getSourceRange();
|
||||
}
|
||||
|
||||
|
|
|
@ -38,7 +38,7 @@ void test() {
|
|||
int i;
|
||||
i = 1 << (WORD_BIT - 2);
|
||||
i = 2 << (WORD_BIT - 1); // expected-warning {{bits to represent, but 'int' only has}}
|
||||
i = 1 << (WORD_BIT - 1); // expected-warning {{overrides the sign bit of the shift expression}}
|
||||
i = 1 << (WORD_BIT - 1); // expected-warning {{sets the sign bit of the shift expression}}
|
||||
i = -1 << (WORD_BIT - 1);
|
||||
i = 0 << (WORD_BIT - 1);
|
||||
i = (char)1 << (WORD_BIT - 2);
|
||||
|
|
Loading…
Reference in New Issue